From: Marek Habersack Date: Fri, 30 Nov 2012 09:59:01 +0000 (-0800) Subject: Merge pull request #498 from Unroll-Me/master X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=9f3ef8e4bac11601a2cf2670cbab337e6276103b;hp=3af50114d986e9ffcd1544aa7ff13f7472992687;p=mono.git Merge pull request #498 from Unroll-Me/master Fix HttpContextWrapper.Session when Session State is disabled --- diff --git a/.gitmodules b/.gitmodules index 31b22e7b4e1..3ee5ea04262 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,12 @@ [submodule "external/entityframework"] path = external/entityframework url = git://github.com/mono/entityframework.git +[submodule "external/rx"] + path = external/rx + url = git://github.com/mono/rx.git +[submodule "external/ikvm"] + path = external/ikvm + url = git://github.com/mono/ikvm-fork.git +[submodule "external/Lucene.Net"] + path = external/Lucene.Net + url = git://github.com/apache/lucene.net.git diff --git a/LICENSE b/LICENSE index 0c52cc7dc95..19ed03acc96 100644 --- a/LICENSE +++ b/LICENSE @@ -51,6 +51,13 @@ For comments, corrections and updates, please contact mono@xamarin.com Contact mono@xamarin.com for details on obtaining the Mono runtime under other terms. +** mono/support: MonoPosixHelper and support code + + This code is dual licensed under the LGPL or commercial licenses, with + the same guidelines as mono/mono code. + + The ZLib files are included under a "new BSD"-style license. + ** mono/eglib: Mono's X11 glib implementation This is a minimal subset of glib that is to be licensed under diff --git a/Makefile.am b/Makefile.am index b90fd674196..a533344a76c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 MOONLIGHT_SUBDIRS = $(libgc_dir) eglib/src mono +MONOTOUCH_SUBDIRS = $(libgc_dir) eglib/src mono if CROSS_COMPILING SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) data runtime scripts man samples msvc $(docs_dir) @@ -8,6 +9,9 @@ SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) data runtime scripts man ## 'tools' is not normally built DIST_SUBDIRS = m4 po libgc eglib mono ikvm-native data runtime scripts man samples tools msvc docs else +if ONLY_MONOTOUCH +SUBDIRS = $(MONOTOUCH_SUBDIRS) runtime +else if ONLY_MOONLIGHT SUBDIRS = $(MOONLIGHT_SUBDIRS) runtime else @@ -17,6 +21,7 @@ SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) support data runtime scr DIST_SUBDIRS = m4 po libgc eglib mono ikvm-native support data runtime scripts man samples tools msvc docs endif endif +endif all: update_submodules @@ -112,6 +117,31 @@ moon-do-clean: endif +if INSTALL_MONOTOUCH +monotouch-do-build: config.h + @list='$(MONOTOUCH_SUBDIRS)'; for subdir in $$list; do \ + case "x$$subdir" in \ + xmono ) target="monotouch-do-build";; \ + * ) target="all";; \ + esac; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ + done; + (cd runtime && $(MAKE) $(AM_MAKEFLAGS) monotouch-do-build) + +monotouch-do-clean: + @list='$(MONOTOUCH_SUBDIRS)'; for subdir in $$list; do \ + case "x$$subdir" in \ + xmono ) target="monotouch-do-clean";; \ + * ) target="clean";; \ + esac; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ + done; + (cd runtime && $(MAKE) $(AM_MAKEFLAGS) monotouch-do-clean) + +endif + win32getdeps: wget http://www.go-mono.com/archive/pkgconfig-0.11-20020310.zip wget http://www.go-mono.com/archive/glib-2.0.4-20020703.zip diff --git a/autogen.sh b/autogen.sh index 479425a5dc0..c25a1f72c20 100755 --- a/autogen.sh +++ b/autogen.sh @@ -103,7 +103,7 @@ if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then fi echo "Running aclocal -I m4 -I . $ACLOCAL_FLAGS ..." -aclocal -W none -I m4 -I . $ACLOCAL_FLAGS || { +aclocal -Wnone -I m4 -I . $ACLOCAL_FLAGS || { echo echo "**Error**: aclocal failed. This may mean that you have not" echo "installed all of the packages you need, or you may need to" diff --git a/configure.in b/configure.in index f3ad820db5f..48a6a469145 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script. #AC_PREREQ([2.62]) -AC_INIT(mono, [3.0.1], +AC_INIT(mono, [3.0.2], [http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono]) AC_CONFIG_SRCDIR([README]) @@ -89,6 +89,7 @@ esac host_win32=no target_win32=no platform_android=no +platform_darwin=no case "$host" in *-mingw*|*-*-cygwin*) AC_DEFINE(HOST_WIN32,1,[Host Platform is Win32]) @@ -295,8 +296,6 @@ case "$host" in CPPFLAGS="$CPPFLAGS -no-cpp-precomp -D_THREAD_SAFE -DGC_MACOSX_THREADS -DPLATFORM_MACOSX -DUSE_MMAP -DUSE_MUNMAP" CPPFLAGS="$CPPFLAGS -DGetCurrentProcess=MonoGetCurrentProcess -DGetCurrentThread=MonoGetCurrentThread -DCreateEvent=MonoCreateEvent" libmono_cflags="-D_THREAD_SAFE" - LDFLAGS="$LDFLAGS -pthread" - libmono_ldflags="-pthread" need_link_unlink=yes AC_DEFINE(PTHREAD_POINTER_ID) AC_DEFINE(USE_MACH_SEMA, 1, [...]) @@ -313,7 +312,7 @@ case "$host" in case "$host" in dnl Snow Leopard and newer config.guess reports as this i*86-*-darwin*) - BROKEN_DARWIN_FLAGS="-arch i386 -D_XOPEN_SOURCE -mmacosx-version-min=10.5" + BROKEN_DARWIN_FLAGS="-arch i386 -D_XOPEN_SOURCE" CPPFLAGS="$CPPFLAGS $BROKEN_DARWIN_FLAGS" CFLAGS="$CFLAGS $BROKEN_DARWIN_FLAGS" CXXFLAGS="$CXXFLAGS $BROKEN_DARWIN_FLAGS" @@ -323,6 +322,9 @@ case "$host" in CPPFLAGS_FOR_EGLIB="$CPPFLAGS_FOR_EGLIB $BROKEN_DARWIN_FLAGS" CFLAGS_FOR_EGLIB="$CFLAGS_FOR_EGLIB $BROKEN_DARWIN_FLAGS" ;; + arm*-darwin*) + has_dtrace=no + ;; esac ;; *-*-haiku*) @@ -490,7 +492,7 @@ AC_CHECK_SIZEOF(void *, 4) WARN='' if test x"$GCC" = xyes; then - WARN='-Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch-enum' + WARN='-Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value' # The runtime code does not respect ANSI C strict aliasing rules CFLAGS="$CFLAGS -fno-strict-aliasing" @@ -533,14 +535,12 @@ CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -g" AC_CACHE_CHECK([for clang], mono_cv_clang,[ - AC_TRY_RUN([ - int main () { - #ifdef __clang__ - return 0; - #else - return 1; - #endif - } + AC_TRY_COMPILE([], [ + #ifdef __clang__ + #else + #error "FAILED" + #endif + return 0; ], [mono_cv_clang=yes], [mono_cv_clang=no], @@ -694,6 +694,8 @@ if test "x$enable_libraries" = "xno"; then with_shared_mono=no fi +AM_CONDITIONAL(DISABLE_LIBRARIES, test x$enable_libraries = xno) + case $host in *nacl* ) with_shared_mono=yes;; esac @@ -738,7 +740,8 @@ DISABLED_FEATURES=none AC_ARG_ENABLE(minimal, [ --enable-minimal=LIST drop support for LIST subsystems. LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, - reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, normalization, assembly_remapping, shared_perfcounters.], + reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, perfcounters, normalization, assembly_remapping, shared_perfcounters, + sgen_remset, sgen_marksweep_par, sgen_marksweep_fixed, sgen_marksweep_fixed_par, sgen_copying.], [ for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do eval "mono_feature_disable_$feature='yes'" @@ -853,6 +856,10 @@ if test "x$mono_feature_disable_soft_debug" = "xyes"; then AC_MSG_NOTICE([Disabled Soft Debugger.]) fi +if test "x$mono_feature_disable_perfcounters" = "xyes"; then + AC_DEFINE(DISABLE_PERFCOUNTERS, 1, [Disable Performance Counters.]) + AC_MSG_NOTICE([Disabled Performance Counters.]) +fi if test "x$mono_feature_disable_normalization" = "xyes"; then AC_DEFINE(DISABLE_NORMALIZATION, 1, [Disable String normalization support.]) AC_MSG_NOTICE([Disabled String normalization support.]) @@ -868,6 +875,31 @@ if test "x$mono_feature_disable_shared_perfcounters" = "xyes"; then AC_MSG_NOTICE([Disabled Shared perfcounters.]) fi +if test "x$mono_feature_disable_sgen_remset" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_REMSET, 1, [Disable wbarrier=remset support in SGEN.]) + AC_MSG_NOTICE([Disabled wbarrier=remset support in SGEN.]) +fi + +if test "x$mono_feature_disable_sgen_marksweep_par" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_MAJOR_MARKSWEEP_PAR, 1, [Disable major=marksweep-par support in SGEN.]) + AC_MSG_NOTICE([Disabled major=marksweep-par support in SGEN.]) +fi + +if test "x$mono_feature_disable_sgen_marksweep_fixed" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_MAJOR_MARKSWEEP_FIXED, 1, [Disable major=marksweep-fixed support in SGEN.]) + AC_MSG_NOTICE([Disabled major=marksweep-fixed support in SGEN.]) +fi + +if test "x$mono_feature_disable_sgen_marksweep_fixed_par" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_MAJOR_MARKSWEEP_FIXED_PAR, 1, [Disable major=marksweep-fixed-par support in SGEN.]) + AC_MSG_NOTICE([Disabled major=marksweep-fixed-par support in SGEN.]) +fi + +if test "x$mono_feature_disable_sgen_copying" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_MAJOR_COPYING, 1, [Disable major=copying support in SGEN.]) + AC_MSG_NOTICE([Disabled major=copying support in SGEN.]) +fi + AC_ARG_ENABLE(executables, [ --disable-executables disable the build of the runtime executables], enable_executables=$enableval, enable_executables=yes) AM_CONDITIONAL(DISABLE_EXECUTABLES, test x$enable_executables = xno) @@ -1553,11 +1585,11 @@ if test x$target_win32 = xno; then return 0; } - for (i = 0; i < 3; ++i) { - sleep (1); + for (i = 0; i < 300; ++i) { waitpid (son, &status, WNOHANG); if (WIFEXITED (status) && WEXITSTATUS (status) == 0) return 0; + usleep (10000); } kill (son, SIGKILL); @@ -1659,9 +1691,21 @@ if test x$target_win32 = xno; then havekqueue=no AC_CHECK_FUNCS(kqueue, , AC_MSG_CHECKING(for kqueue in sys/event.h) AC_TRY_LINK([#include ], - [ kqueue(); ], - AC_DEFINE(HAVE_KQUEUE, 1, [Have kqueue]) AC_MSG_RESULT(yes), - AC_MSG_RESULT(no))) + [ kqueue(); ],[havekqueue=yes],[])) + + dnl ************************************** + dnl * Darwin has a race that prevents us from using reliably: + dnl * http://lists.apple.com/archives/darwin-dev/2011/Jun/msg00016.html + dnl * Since kqueue is mostly used for scaling large web servers, + dnl * and very few folks run Mono on large web servers on OSX, falling + dnl * back + dnl ************************************** + if test x$havekqueue = xyes; then + if x$platform_darwin = xno; then + AC_DEFINE(USE_KQUEUE_FOR_THREADPOOL, 1, [Use kqueue for the threadpool]) + fi + fi + dnl ****************************** dnl *** Checks for SIOCGIFCONF *** dnl ****************************** @@ -2168,13 +2212,21 @@ if test "x$enable_llvm" = "xyes"; then AC_MSG_ERROR([llvm-config not found.]) fi + llvm_codegen="x86codegen" + case "$target" in + arm*) + llvm_codegen="armcodegen" + ;; + esac + + # The output of --cflags seems to include optimizations flags too LLVM_CFLAGS=`$LLVM_CONFIG --cflags | sed -e 's/-O2//g' | sed -e 's/-O0//g' | sed -e 's/-fomit-frame-pointer//g' | sed -e 's/-fPIC//g'` # LLVM is compiled with -fno-rtti, so we need this too, since our classes inherit # from LLVM classes. LLVM_CXXFLAGS="`$LLVM_CONFIG --cxxflags` -fno-rtti" LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags` - LLVM_LIBS=`$LLVM_CONFIG --libs core bitwriter jit mcjit x86codegen` + LLVM_LIBS=`$LLVM_CONFIG --libs core bitwriter jit mcjit $llvm_codegen` LLVM_LIBS="$LLVM_LDFLAGS $LLVM_LIBS -lstdc++" # Should be something like '2.6' or '2.7svn' @@ -2444,6 +2496,17 @@ if test "x$host" != "x$target"; then AC_DEFINE(MONO_CROSS_COMPILE,1,[The runtime is compiled for cross-compiling mode]) enable_mcs_build=no case "$target" in + arm*-darwin*) + TARGET=ARM; + arch_target=arm; + ACCESS_UNALIGNED="no" + JIT_SUPPORTED=yes + CPPFLAGS="$CPPFLAGS -DARM_FPU_VFP=1 -D__ARM_EABI__ -DHAVE_ARMV6=1" + jit_wanted=true + # Can't use tls, since it depends on the runtime detection of tls offsets + # in mono-compiler.h + with_tls=pthread + ;; powerpc64-ps3-linux-gnu) TARGET=POWERPC64 arch_target=powerpc64 @@ -2478,7 +2541,7 @@ if test "x$host" != "x$target"; then AC_DEFINE(TARGET_X86, 1, [...]) sizeof_register=4 ;; - arm*-unknown-linux-gnueabi*) + arm*-unknown-linux-*) TARGET=ARM; arch_target=arm; AC_DEFINE(TARGET_ARM, 1, [...]) @@ -2533,6 +2596,21 @@ MIPS) esac if test "x$target_mach" = "xyes"; then + AC_TRY_COMPILE([#include "TargetConditionals.h"],[ + #if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1 + #error fail this for ios + #endif + return 0; + ], [ + AC_DEFINE(TARGET_OSX,1,[The JIT/AOT targets OSX]) + CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_OSX" + CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_OSX" + ], [ + AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS]) + CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS" + CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS" + ]) + AC_DEFINE(TARGET_MACH,1,[The JIT/AOT targets Apple platforms]) fi @@ -2720,6 +2798,11 @@ if test "x$icall_tables" = "xno"; then AC_DEFINE(DISABLE_ICALL_TABLES, 1, [Icall tables disabled]) fi +if test "x$mono_cv_clang" = "xyes"; then + # FIXME: This causes many compilation errors + with_tls=pthread +fi + if test "x$with_tls" = "x__thread"; then AC_DEFINE(HAVE_KW_THREAD, 1, [Have __thread keyword]) # Pass the information to libgc @@ -2816,6 +2899,7 @@ AC_ARG_WITH(profile4, [ --with-profile4=yes,no If you want to install AC_ARG_WITH(profile4_5,[ --with-profile4_5=yes,no If you want to install the 4.5 FX (defaults to yes)], [], [with_profile4_5=yes]) AC_ARG_WITH(monodroid, [ --with-monodroid=yes,no If you want to build the MonoDroid assemblies (defaults to no)], [], [with_monodroid=no]) AC_ARG_WITH(monotouch, [ --with-monotouch=yes,no,only If you want to build the MonoTouch assemblies (defaults to no)], [], [with_monotouch=no]) +AC_ARG_WITH(mobile, [ --with-mobile=yes,no If you want to build the Mobile assemblies (defaults to no)], [], [with_mobile=no]) OPROFILE=no AC_ARG_WITH(oprofile,[ --with-oprofile=no, Enable oprofile support (defaults to no)],[ @@ -2864,6 +2948,12 @@ AC_ARG_WITH(moon_gc, [ --with-moon-gc=boehm,sgen Select the gc to use with Moo fi ], [with_moon_gc=boehm]) +AC_ARG_WITH(lazy_gc_thread_creation, [ --with-lazy-gc-thread-creation=yes|no Enable lazy runtime thread creation, embedding host must do it explicitly (defaults to no)],[ + if test x$with_lazy_gc_thread_creation != xno ; then + AC_DEFINE(LAZY_GC_THREAD_CREATION,1,[Enable lazy gc thread creation by the embedding host.]) + fi +], [with_lazy_gc_thread_creation=no]) + AC_CHECK_HEADER([malloc.h], [AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1], [Define to 1 if you have /usr/include/malloc.h.])],,) @@ -2878,7 +2968,7 @@ fi # When --disable-shared is used, libtool transforms libmono-2.0.la into libmono-2.0.so # instead of libmono-static.a -if test "x$enable_shared" = "xno"; then +if test "x$enable_shared" = "xno" -a "x$enable_executables" = "xyes"; then LIBMONO_LA=libmini-static.la else LIBMONO_LA=libmono-$API_VER.la @@ -2924,6 +3014,8 @@ AM_CONDITIONAL(INSTALL_4_0, [test "x$with_profile4" = xyes]) AM_CONDITIONAL(INSTALL_4_5, [test "x$with_profile4_5" = xyes]) AM_CONDITIONAL(INSTALL_MONODROID, [test "x$with_monodroid" != "xno"]) AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" != "xno"]) +AM_CONDITIONAL(INSTALL_MOBILE, [test "x$with_mobile" = xyes]) +AM_CONDITIONAL(ONLY_MONOTOUCH, [test "x$with_monotouch" = "xonly"]) AM_CONDITIONAL(MIPS_GCC, test ${TARGET}${ac_cv_prog_gcc} = MIPSyes) AM_CONDITIONAL(MIPS_SGI, test ${TARGET}${ac_cv_prog_gcc} = MIPSno) @@ -2944,6 +3036,7 @@ AM_CONDITIONAL(HPPA, test x$TARGET = xHPPA) AM_CONDITIONAL(HOST_X86, test x$HOST = xX86) AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64) AM_CONDITIONAL(HOST_ARM, test x$HOST = xARM) +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) diff --git a/docs/reactive-extension-bundle.txt b/docs/reactive-extension-bundle.txt new file mode 100644 index 00000000000..175818a63be --- /dev/null +++ b/docs/reactive-extension-bundle.txt @@ -0,0 +1,49 @@ +With this change, we bundle Reactive Extensions from Microsoft. + +Steps to do: + +- Until we add submodule, check out Rx sources from http://rx.codeplex.com: + + $ cd external + $ git clone git://github.com/atsushieno/rx.git + $ cd rx + $ git checkout rx-oss-v1.0 + $ cd ../.. + + Note that the original repo at rx.codeplex.com will *fail* on Linux! + codeplex.codeplex.com/workitem/26133 + Also note that rx.codeplex.com is huge and takes very long time to checkout. + +- expand rx-mono-changes-3.tar.bz2 + + $ tar jxvf rx-mono-changes-3.tar.bz2 + +- Apply changes to mcs/class/Makefile: + + $ cd mcs/class + $ patch -i add-rx-libs.patch -p3 + $ cd ../.. + +Then it should be done. + +Note that this does not include Mono.Reactive.Testing into the build yet - +this library depends on nunit.framework.dll but it wouldn't be built before +this assembly is built. This needs to be resolved. + +** Current Status + +- We don't have Microsoft.Reactive.Testing.dll. Instead, I created an + alternative Mono.Reactive.Testing.dll which *mostly* uses MS sources for + that assembly but uses NUnit.Framework instead. + + To make it happen, I added a small script that automatically replaces + MSTest dependency parts with that for NUnit (replacer.sh under rx tree). + + (We'll also have to rename namespaces and have more source changes, but + so far it is to get things runnable.) + +- To check the build sanity, I imported unit tests (as explained above) + and it is supposed to run by "make run-test" in Mono.Reactive.Testing + directory (the tests were all in one place in MS tests, so I made it + in Mono.Reactive.Testing directory instead). + diff --git a/docs/sources/mono-api-decimal.html b/docs/sources/mono-api-decimal.html new file mode 100644 index 00000000000..41c9347811f --- /dev/null +++ b/docs/sources/mono-api-decimal.html @@ -0,0 +1,19 @@ +

Decimal Support

+ +

You can use the mono_decimal functions to access and + manipulate System.Decimal types from C. + +

mono_decimal2double

+

mono_decimal2Int64

+

mono_decimal2string

+

mono_decimal2UInt64

+

mono_decimalCompare

+

mono_decimalDiv

+

mono_decimalFloorAndTrunc

+

mono_decimalIncr

+

mono_decimalIntDiv

+

mono_decimalMult

+

mono_decimalRound

+

mono_decimalSetExponent

+

mono_double2decimal

+

mono_string2decimal

diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 4b03a191ed0..69122ddda62 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -58,6 +58,30 @@ out_vfprintf (FILE *ignore, const gchar *format, va_list args) /* TODO: provide a proper app name */ __android_log_vprint (ANDROID_LOG_ERROR, "mono", format, args); } +#elif MONOTOUCH && defined(__arm__) +#include + +static int +to_asl_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT; + case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR; + case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING; + case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE; + case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO; + case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG; + } + return ASL_LEVEL_ERR; +} + +static void +out_vfprintf (FILE *ignore, const gchar *format, va_list args) +{ + asl_vlog (NULL, NULL, ASL_LEVEL_WARNING, format, args); +} + #else static void out_vfprintf (FILE *file, const gchar *format, va_list args) @@ -116,6 +140,8 @@ g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, { #if PLATFORM_ANDROID __android_log_vprint (to_android_priority (log_level), log_domain, format, args); +#elif MONOTOUCH && defined(__arm__) + asl_vlog (NULL, NULL, to_asl_priority (log_level), format, args); #else char *msg; diff --git a/external/Lucene.Net b/external/Lucene.Net new file mode 160000 index 00000000000..88fb67b0762 --- /dev/null +++ b/external/Lucene.Net @@ -0,0 +1 @@ +Subproject commit 88fb67b07621dfed054d8d75fd50672fb26349df diff --git a/external/ikvm b/external/ikvm new file mode 160000 index 00000000000..b85c0f4a87f --- /dev/null +++ b/external/ikvm @@ -0,0 +1 @@ +Subproject commit b85c0f4a87f539dc84933aa2409e20f6499c2f63 diff --git a/external/rx b/external/rx new file mode 160000 index 00000000000..7c59a20c72a --- /dev/null +++ b/external/rx @@ -0,0 +1 @@ +Subproject commit 7c59a20c72adc9b4c7568ce0395fe33e0a4bf8ea diff --git a/libgc/autogen.sh b/libgc/autogen.sh index ceea56c962f..4cfc38728ee 100755 --- a/libgc/autogen.sh +++ b/libgc/autogen.sh @@ -87,6 +87,7 @@ if grep "^AC_PROG_LIBTOOL" configure.in >/dev/null; then fi fi +ACLOCAL_FLAGS="$ACLOCAL_FLAGS -Wnone" echo "Running aclocal $ACLOCAL_FLAGS ..." aclocal $ACLOCAL_FLAGS || { echo @@ -104,7 +105,7 @@ if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then fi echo "Running automake --gnu $am_opt ..." -automake --add-missing --gnu $am_opt || +automake --add-missing --gnu -Wno-obsolete $am_opt || { echo "**Error**: automake failed."; exit 1; } echo "Running autoconf ..." autoconf || { echo "**Error**: autoconf failed."; exit 1; } diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index a1051f5ac4e..a53cda354a6 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -115,7 +115,7 @@ void GC_push_all_stacks() { if(r != KERN_SUCCESS) continue; #if defined(I386) -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +#if defined (TARGET_IOS) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) lo = state.__esp; @@ -391,7 +391,7 @@ void GC_push_all_stacks() { (natural_t *)&info, &outCount); if(r != KERN_SUCCESS) continue; -#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +#if defined (TARGET_IOS) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) lo = (void*)info.__esp; hi = (ptr_t)FindTopOfStack(info.__esp); diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h index da15e905c58..ec53e3a95ea 100644 --- a/libgc/include/private/gcconfig.h +++ b/libgc/include/private/gcconfig.h @@ -312,6 +312,7 @@ # define mach_type_known # endif # ifdef DARWIN +# include "TargetConditionals.h" # if defined(__ppc__) || defined(__ppc64__) # define POWERPC # define mach_type_known @@ -320,7 +321,9 @@ # define mach_type_known # define DARWIN_DONT_PARSE_STACK # define OS_TYPE "DARWIN" -# define DYNAMIC_LOADING +# if TARGET_IPHONE_SIMULATOR == 0 +# define DYNAMIC_LOADING +# endif /* XXX: see get_end(3), get_etext() and get_end() should not be used. These aren't used when dyld support is enabled (it is by default) */ # define DATASTART ((ptr_t) get_etext()) diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c index bc31c9733a7..ccafb3b1169 100644 --- a/libgc/pthread_support.c +++ b/libgc/pthread_support.c @@ -66,6 +66,7 @@ --> Macro replaced by USE_COMPILER_TLS # endif +#ifndef USE_COMPILER_TLS # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \ defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \ defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC) || \ @@ -73,6 +74,7 @@ defined(GC_OPENBSD_THREADS) # define USE_PTHREAD_SPECIFIC # endif +#endif # if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE) # define _POSIX4A_DRAFT10_SOURCE 1 diff --git a/mcs/build/library.make b/mcs/build/library.make index ad8d8e04604..768149e9d10 100644 --- a/mcs/build/library.make +++ b/mcs/build/library.make @@ -310,7 +310,7 @@ $(makefrag) $(test_response) $(test_makefrag) $(btest_response) $(btest_makefrag Q_MDOC_UP=$(if $(V),,@echo "MDOC-UP [$(PROFILE)] $(notdir $(@))";) # net_2_0 is needed because monodoc is only compiled in that profile MDOC_UP =$(Q_MDOC_UP) \ - MONO_PATH="$(topdir)/class/lib/$(DEFAULT_PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/tools/mdoc/mdoc.exe \ + MONO_PATH="$(topdir)/class/lib/$(DEFAULT_PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/class/lib/$(DEFAULT_PROFILE)/mdoc.exe \ update --delete -o Documentation/en $(the_lib) doc-update-local: $(the_libdir)/.doc-stamp diff --git a/mcs/build/profiles/monotouch.make b/mcs/build/profiles/monotouch.make index 5a33a9f0627..26d5f97a26d 100644 --- a/mcs/build/profiles/monotouch.make +++ b/mcs/build/profiles/monotouch.make @@ -5,6 +5,9 @@ BOOTSTRAP_PROFILE = build BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) +# Use system resgen as we don't want local System.Windows.Forms dependency +RESGEN = resgen2 + profile-check: @: diff --git a/mcs/build/profiles/monotouch_runtime.make b/mcs/build/profiles/monotouch_runtime.make index c153792f1b9..a6540aa52a2 100644 --- a/mcs/build/profiles/monotouch_runtime.make +++ b/mcs/build/profiles/monotouch_runtime.make @@ -14,3 +14,6 @@ DEFAULT_REFERENCES = -r:mscorlib.dll PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_3_0 -d:NET_3_5 -d:NET_4_0 -d:NET_4_5 -nowarn:1699 -nostdlib -lib:$(topdir)/class/lib/$(PROFILE) $(DEFAULT_REFERENCES) $(PLATFORM_DEBUG_FLAGS) FRAMEWORK_VERSION = 4.5 + +# This is utility build only +NO_INSTALL = yes diff --git a/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs b/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs index a6e19404b37..009c03b6bb7 100755 --- a/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs +++ b/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs @@ -83,8 +83,8 @@ namespace Commons.Xml.Relaxng RelaxngGrammar g = null; RelaxngPattern p; try { - if (grammar.IsSourceCompactSyntax) { - p = RncParser.ParseRnc (new StreamReader ((Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream))), null, BaseUri, nsContext); + if (uri.AbsolutePath.EndsWith(".rnc", StringComparison.InvariantCultureIgnoreCase)) { + p = RncParser.ParseRnc (new StreamReader ((Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream))), null, uri.AbsoluteUri, nsContext); } else { xtr = new XmlTextReader (uri.AbsoluteUri, (Stream) grammar.Resolver.GetEntity (uri, null, typeof (Stream))); RelaxngReader r = new RelaxngReader (xtr, nsContext, grammar.Resolver); diff --git a/mcs/class/IKVM.Reflection/AmbiguousMatchException.cs b/mcs/class/IKVM.Reflection/AmbiguousMatchException.cs deleted file mode 100644 index 121d69fbaa1..00000000000 --- a/mcs/class/IKVM.Reflection/AmbiguousMatchException.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.Serialization; - -namespace IKVM.Reflection -{ - [Serializable] - public sealed class AmbiguousMatchException : Exception - { - public AmbiguousMatchException() - { - } - - public AmbiguousMatchException(string message) - : base(message) - { - } - - public AmbiguousMatchException(string message, Exception inner) - : base(message, inner) - { - } - - private AmbiguousMatchException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } -} diff --git a/mcs/class/IKVM.Reflection/Assembly.cs b/mcs/class/IKVM.Reflection/Assembly.cs deleted file mode 100644 index 715e774bdeb..00000000000 --- a/mcs/class/IKVM.Reflection/Assembly.cs +++ /dev/null @@ -1,201 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; - -namespace IKVM.Reflection -{ - public abstract class Assembly : ICustomAttributeProvider - { - internal readonly Universe universe; - protected string fullName; // AssemblyBuilder needs access to this field to clear it when the name changes - - internal Assembly(Universe universe) - { - this.universe = universe; - } - - public sealed override string ToString() - { - return FullName; - } - - public abstract Type[] GetTypes(); - public abstract AssemblyName GetName(); - public abstract string ImageRuntimeVersion { get; } - public abstract Module ManifestModule { get; } - public abstract MethodInfo EntryPoint { get; } - public abstract string Location { get; } - public abstract AssemblyName[] GetReferencedAssemblies(); - public abstract Module[] GetModules(bool getResourceModules); - public abstract Module[] GetLoadedModules(bool getResourceModules); - public abstract Module GetModule(string name); - public abstract string[] GetManifestResourceNames(); - public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName); - public abstract System.IO.Stream GetManifestResourceStream(string name); - - internal abstract Type FindType(TypeName name); - internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName); - - // The differences between ResolveType and FindType are: - // - ResolveType is only used when a type is assumed to exist (because another module's metadata claims it) - // - ResolveType can return a MissingType - internal Type ResolveType(TypeName typeName) - { - return FindType(typeName) ?? universe.GetMissingTypeOrThrow(this.ManifestModule, null, typeName); - } - - public string FullName - { - get { return fullName ?? (fullName = GetName().FullName); } - } - - public Module[] GetModules() - { - return GetModules(true); - } - - public Module[] GetLoadedModules() - { - return GetLoadedModules(true); - } - - public AssemblyName GetName(bool copiedName) - { - return GetName(); - } - - public bool ReflectionOnly - { - get { return true; } - } - - public Type[] GetExportedTypes() - { - List list = new List(); - foreach (Type type in GetTypes()) - { - if (type.IsVisible) - { - list.Add(type); - } - } - return list.ToArray(); - } - - public Type GetType(string name) - { - return GetType(name, false); - } - - public Type GetType(string name, bool throwOnError) - { - return GetType(name, throwOnError, false); - } - - public Type GetType(string name, bool throwOnError, bool ignoreCase) - { - TypeNameParser parser = TypeNameParser.Parse(name, throwOnError); - if (parser.Error) - { - return null; - } - if (parser.AssemblyName != null) - { - if (throwOnError) - { - throw new ArgumentException("Type names passed to Assembly.GetType() must not specify an assembly."); - } - else - { - return null; - } - } - TypeName typeName = TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart)); - Type type = ignoreCase - ? FindTypeIgnoreCase(typeName.ToLowerInvariant()) - : FindType(typeName); - if (type == null && __IsMissing) - { - throw new MissingAssemblyException((MissingAssembly)this); - } - return parser.Expand(type, this, throwOnError, name, false, ignoreCase); - } - - public virtual Module LoadModule(string moduleName, byte[] rawModule) - { - throw new NotSupportedException(); - } - - public Module LoadModule(string moduleName, byte[] rawModule, byte[] rawSymbolStore) - { - return LoadModule(moduleName, rawModule); - } - - public bool IsDefined(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0; - } - - public IList __GetCustomAttributes(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit); - } - - public static string CreateQualifiedName(string assemblyName, string typeName) - { - return typeName + ", " + assemblyName; - } - - public static Assembly GetAssembly(Type type) - { - return type.Assembly; - } - - public string CodeBase - { - get - { - string path = this.Location.Replace(System.IO.Path.DirectorySeparatorChar, '/'); - if (!path.StartsWith("/")) - { - path = "/" + path; - } - return "file://" + path; - } - } - - public virtual bool __IsMissing - { - get { return false; } - } - - public virtual AssemblyNameFlags __AssemblyFlags - { - get { return GetName().Flags; } - } - - internal abstract IList GetCustomAttributesData(Type attributeType); - } -} diff --git a/mcs/class/IKVM.Reflection/AssemblyName.cs b/mcs/class/IKVM.Reflection/AssemblyName.cs deleted file mode 100644 index 0812194b844..00000000000 --- a/mcs/class/IKVM.Reflection/AssemblyName.cs +++ /dev/null @@ -1,437 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Globalization; -using System.Configuration.Assemblies; -using System.IO; -using System.Text; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - public sealed class AssemblyName : ICloneable - { - private string name; - private string culture; - private Version version; - private byte[] publicKeyToken; - private byte[] publicKey; - private StrongNameKeyPair keyPair; - private AssemblyNameFlags flags; - private AssemblyHashAlgorithm hashAlgorithm; - private AssemblyVersionCompatibility versionCompatibility = AssemblyVersionCompatibility.SameMachine; - private string codeBase; - internal byte[] hash; - - public AssemblyName() - { - } - - public AssemblyName(string assemblyName) - { - if (assemblyName == null) - { - throw new ArgumentNullException("assemblyName"); - } - if (assemblyName == "") - { - throw new ArgumentException(); - } - ParsedAssemblyName parsed; - switch (Fusion.ParseAssemblyName(assemblyName, out parsed)) - { - case ParseAssemblyResult.GenericError: - throw new FileLoadException(); - case ParseAssemblyResult.DuplicateKey: - throw new System.Runtime.InteropServices.COMException(); - } - name = parsed.Name; - if (parsed.Culture != null) - { - if (parsed.Culture.Equals("neutral", StringComparison.InvariantCultureIgnoreCase)) - { - culture = ""; - } - else if (parsed.Culture == "") - { - throw new FileLoadException(); - } - else - { - culture = new CultureInfo(parsed.Culture).Name; - } - } - if (parsed.Version != null && parsed.Version.Major != 65535 && parsed.Version.Minor != 65535) - { - // our Fusion parser returns -1 for build and revision for incomplete version numbers (and we want 65535) - version = new Version(parsed.Version.Major, parsed.Version.Minor, parsed.Version.Build & 0xFFFF, parsed.Version.Revision & 0xFFFF); - } - if (parsed.PublicKeyToken != null) - { - if (parsed.PublicKeyToken.Equals("null", StringComparison.InvariantCultureIgnoreCase)) - { - publicKeyToken = Empty.Array; - } - else if (parsed.PublicKeyToken.Length != 16) - { - throw new FileLoadException(); - } - else - { - publicKeyToken = new byte[8]; - for (int i = 0, pos = 0; i < publicKeyToken.Length; i++, pos += 2) - { - publicKeyToken[i] = (byte)("0123456789abcdef".IndexOf(char.ToLowerInvariant(parsed.PublicKeyToken[pos])) * 16 - + "0123456789abcdef".IndexOf(char.ToLowerInvariant(parsed.PublicKeyToken[pos + 1]))); - } - } - } - if (parsed.Retargetable.HasValue) - { - if (parsed.Culture == null || parsed.PublicKeyToken == null || parsed.Version == null || parsed.Version.Build == -1 || parsed.Version.Revision == -1) - { - throw new FileLoadException(); - } - if (parsed.Retargetable.Value) - { - flags |= AssemblyNameFlags.Retargetable; - } - } - ProcessorArchitecture = parsed.ProcessorArchitecture; - if (parsed.WindowsRuntime) - { - ContentType = AssemblyContentType.WindowsRuntime; - } - } - - public override string ToString() - { - return FullName; - } - - public string Name - { - get { return name; } - set { name = value; } - } - - public CultureInfo CultureInfo - { - get { return culture == null ? null : new CultureInfo(culture); } - set { culture = value == null ? null : value.Name; } - } - - internal string Culture - { - get { return culture; } - set { culture = value; } - } - - public Version Version - { - get { return version; } - set { version = value; } - } - - public StrongNameKeyPair KeyPair - { - get { return keyPair; } - set { keyPair = value; } - } - - public string CodeBase - { - get { return codeBase; } - set { codeBase = value; } - } - - public string EscapedCodeBase - { - get - { - // HACK use the real AssemblyName to escape the codebase - System.Reflection.AssemblyName tmp = new System.Reflection.AssemblyName(); - tmp.CodeBase = codeBase; - return tmp.EscapedCodeBase; - } - } - - public ProcessorArchitecture ProcessorArchitecture - { - get { return (ProcessorArchitecture)(((int)flags & 0x70) >> 4); } - set - { - if (value >= ProcessorArchitecture.None && value <= ProcessorArchitecture.Arm) - { - flags = (flags & ~(AssemblyNameFlags)0x70) | (AssemblyNameFlags)((int)value << 4); - } - } - } - - public AssemblyNameFlags Flags - { - get { return flags & (AssemblyNameFlags)~0xEF0; } - set { flags = (flags & (AssemblyNameFlags)0xEF0) | (value & (AssemblyNameFlags)~0xEF0); } - } - - public AssemblyVersionCompatibility VersionCompatibility - { - get { return versionCompatibility; } - set { versionCompatibility = value; } - } - - public AssemblyContentType ContentType - { - get { return (AssemblyContentType)(((int)flags & 0xE00) >> 9); } - set - { - if (value >= AssemblyContentType.Default && value <= AssemblyContentType.WindowsRuntime) - { - flags = (flags & ~(AssemblyNameFlags)0xE00) | (AssemblyNameFlags)((int)value << 9); - } - } - } - - public byte[] GetPublicKey() - { - return publicKey; - } - - public void SetPublicKey(byte[] publicKey) - { - this.publicKey = publicKey; - flags = (flags & ~AssemblyNameFlags.PublicKey) | (publicKey == null ? 0 : AssemblyNameFlags.PublicKey); - } - - public byte[] GetPublicKeyToken() - { - if (publicKeyToken == null && publicKey != null) - { - // note that GetPublicKeyToken() has a side effect in this case, because we retain this token even after the public key subsequently gets changed - publicKeyToken = ComputePublicKeyToken(publicKey); - } - return publicKeyToken; - } - - public void SetPublicKeyToken(byte[] publicKeyToken) - { - this.publicKeyToken = publicKeyToken; - } - - public AssemblyHashAlgorithm HashAlgorithm - { - get { return hashAlgorithm; } - set { hashAlgorithm = value; } - } - - public byte[] __Hash - { - get { return hash; } - } - - public string FullName - { - get - { - if (name == null) - { - return ""; - } - StringBuilder sb = new StringBuilder(); - bool doubleQuotes = name.StartsWith(" ") || name.EndsWith(" ") || name.IndexOf('\'') != -1; - bool singleQuotes = name.IndexOf('"') != -1; - if (singleQuotes) - { - sb.Append('\''); - } - else if (doubleQuotes) - { - sb.Append('"'); - } - if (name.IndexOf(',') != -1 || name.IndexOf('\\') != -1 || name.IndexOf('=') != -1 || (singleQuotes && name.IndexOf('\'') != -1)) - { - for (int i = 0; i < name.Length; i++) - { - char c = name[i]; - if (c == ',' || c == '\\' || c == '=' || (singleQuotes && c == '\'')) - { - sb.Append('\\'); - } - sb.Append(c); - } - } - else - { - sb.Append(name); - } - if (singleQuotes) - { - sb.Append('\''); - } - else if (doubleQuotes) - { - sb.Append('"'); - } - if (version != null) - { - if ((version.Major & 0xFFFF) != 0xFFFF) - { - sb.Append(", Version=").Append(version.Major & 0xFFFF); - if ((version.Minor & 0xFFFF) != 0xFFFF) - { - sb.Append('.').Append(version.Minor & 0xFFFF); - if ((version.Build & 0xFFFF) != 0xFFFF) - { - sb.Append('.').Append(version.Build & 0xFFFF); - if ((version.Revision & 0xFFFF) != 0xFFFF) - { - sb.Append('.').Append(version.Revision & 0xFFFF); - } - } - } - } - } - if (culture != null) - { - sb.Append(", Culture=").Append(culture == "" ? "neutral" : culture); - } - byte[] publicKeyToken = this.publicKeyToken; - if ((publicKeyToken == null || publicKeyToken.Length == 0) && publicKey != null) - { - publicKeyToken = ComputePublicKeyToken(publicKey); - } - if (publicKeyToken != null) - { - sb.Append(", PublicKeyToken="); - if (publicKeyToken.Length == 0) - { - sb.Append("null"); - } - else - { - AppendPublicKey(sb, publicKeyToken); - } - } - if ((Flags & AssemblyNameFlags.Retargetable) != 0) - { - sb.Append(", Retargetable=Yes"); - } - if (ContentType == AssemblyContentType.WindowsRuntime) - { - sb.Append(", ContentType=WindowsRuntime"); - } - return sb.ToString(); - } - } - - private static byte[] ComputePublicKeyToken(byte[] publicKey) - { - if (publicKey.Length == 0) - { - return publicKey; - } - // HACK use the real AssemblyName to convert PublicKey to PublicKeyToken - StringBuilder sb = new StringBuilder("Foo, PublicKey=", 20 + publicKey.Length * 2); - AppendPublicKey(sb, publicKey); - string str = sb.ToString(); - if (str == "Foo, PublicKey=00000000000000000400000000000000") - { - // MONOBUG workaround Mono 2.10 bug (fixed in 2.11) - // it does not return the correct public key token for the ECMA key - return new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }; - } - return new System.Reflection.AssemblyName(str).GetPublicKeyToken(); - } - - private static void AppendPublicKey(StringBuilder sb, byte[] publicKey) - { - for (int i = 0; i < publicKey.Length; i++) - { - sb.Append("0123456789abcdef"[publicKey[i] >> 4]); - sb.Append("0123456789abcdef"[publicKey[i] & 0x0F]); - } - } - - public override bool Equals(object obj) - { - AssemblyName other = obj as AssemblyName; - return other != null && other.FullName == this.FullName; - } - - public override int GetHashCode() - { - return FullName.GetHashCode(); - } - - public object Clone() - { - AssemblyName copy = (AssemblyName)MemberwiseClone(); - copy.publicKey = Copy(publicKey); - copy.publicKeyToken = Copy(publicKeyToken); - return copy; - } - - private static byte[] Copy(byte[] b) - { - return b == null || b.Length == 0 ? b : (byte[])b.Clone(); - } - - public static bool ReferenceMatchesDefinition(AssemblyName reference, AssemblyName definition) - { - // HACK use the real AssemblyName to implement the (broken) ReferenceMatchesDefinition method - return System.Reflection.AssemblyName.ReferenceMatchesDefinition(new System.Reflection.AssemblyName(reference.FullName), new System.Reflection.AssemblyName(definition.FullName)); - } - - public static AssemblyName GetAssemblyName(string path) - { - try - { - path = Path.GetFullPath(path); - using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - ModuleReader module = new ModuleReader(null, null, fs, path); - if (module.Assembly == null) - { - throw new BadImageFormatException("Module does not contain a manifest"); - } - return module.Assembly.GetName(); - } - } - catch (IOException x) - { - throw new FileNotFoundException(x.Message, x); - } - catch (UnauthorizedAccessException x) - { - throw new FileNotFoundException(x.Message, x); - } - } - - internal AssemblyNameFlags RawFlags - { - get { return flags; } - set { flags = value; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/BadImageFormatException.cs b/mcs/class/IKVM.Reflection/BadImageFormatException.cs deleted file mode 100644 index 330f9839d37..00000000000 --- a/mcs/class/IKVM.Reflection/BadImageFormatException.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.Serialization; - -namespace IKVM.Reflection -{ - [Serializable] - public sealed class BadImageFormatException : Exception - { - public BadImageFormatException() - { - } - - public BadImageFormatException(string message) - : base(message) - { - } - - public BadImageFormatException(string message, Exception inner) - : base(message, inner) - { - } - - private BadImageFormatException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } -} diff --git a/mcs/class/IKVM.Reflection/Binder.cs b/mcs/class/IKVM.Reflection/Binder.cs deleted file mode 100644 index a0794512e14..00000000000 --- a/mcs/class/IKVM.Reflection/Binder.cs +++ /dev/null @@ -1,405 +0,0 @@ -/* - Copyright (C) 2010-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Globalization; - -namespace IKVM.Reflection -{ - public abstract class Binder - { - protected Binder() - { - } - - public virtual MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state) - { - throw new InvalidOperationException(); - } - - public virtual FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) - { - throw new InvalidOperationException(); - } - - public virtual object ChangeType(object value, Type type, CultureInfo culture) - { - throw new InvalidOperationException(); - } - - public virtual void ReorderArgumentArray(ref object[] args, object state) - { - throw new InvalidOperationException(); - } - - public abstract MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers); - public abstract PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers); - } - - sealed class DefaultBinder : Binder - { - public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers) - { - int matchCount = 0; - foreach (MethodBase method in match) - { - if (MatchParameterTypes(method.GetParameters(), types)) - { - match[matchCount++] = method; - } - } - - if (matchCount == 0) - { - return null; - } - - if (matchCount == 1) - { - return match[0]; - } - - MethodBase bestMatch = match[0]; - bool ambiguous = false; - for (int i = 1; i < matchCount; i++) - { - bestMatch = SelectBestMatch(bestMatch, match[i], types, ref ambiguous); - } - if (ambiguous) - { - throw new AmbiguousMatchException(); - } - return bestMatch; - } - - private static bool MatchParameterTypes(ParameterInfo[] parameters, Type[] types) - { - if (parameters.Length != types.Length) - { - return false; - } - for (int i = 0; i < parameters.Length; i++) - { - Type sourceType = types[i]; - Type targetType = parameters[i].ParameterType; - if (sourceType != targetType - && !targetType.IsAssignableFrom(sourceType) - && !IsAllowedPrimitiveConversion(sourceType, targetType)) - { - return false; - } - } - return true; - } - - private static MethodBase SelectBestMatch(MethodBase mb1, MethodBase mb2, Type[] types, ref bool ambiguous) - { - switch (MatchSignatures(mb1.MethodSignature, mb2.MethodSignature, types)) - { - case 1: - return mb1; - case 2: - return mb2; - } - - if (mb1.MethodSignature.MatchParameterTypes(mb2.MethodSignature)) - { - int depth1 = GetInheritanceDepth(mb1.DeclaringType); - int depth2 = GetInheritanceDepth(mb2.DeclaringType); - if (depth1 > depth2) - { - return mb1; - } - else if (depth1 < depth2) - { - return mb2; - } - } - - ambiguous = true; - return mb1; - } - - private static int GetInheritanceDepth(Type type) - { - int depth = 0; - while (type != null) - { - depth++; - type = type.BaseType; - } - return depth; - } - - private static int MatchSignatures(MethodSignature sig1, MethodSignature sig2, Type[] types) - { - for (int i = 0; i < sig1.GetParameterCount(); i++) - { - Type type1 = sig1.GetParameterType(i); - Type type2 = sig2.GetParameterType(i); - if (type1 != type2) - { - return MatchTypes(type1, type2, types[i]); - } - } - return 0; - } - - private static int MatchSignatures(PropertySignature sig1, PropertySignature sig2, Type[] types) - { - for (int i = 0; i < sig1.ParameterCount; i++) - { - Type type1 = sig1.GetParameter(i); - Type type2 = sig2.GetParameter(i); - if (type1 != type2) - { - return MatchTypes(type1, type2, types[i]); - } - } - return 0; - } - - private static int MatchTypes(Type type1, Type type2, Type type) - { - if (type1 == type) - { - return 1; - } - if (type2 == type) - { - return 2; - } - bool conv = type1.IsAssignableFrom(type2); - return conv == type2.IsAssignableFrom(type1) ? 0 : conv ? 2 : 1; - } - - private static bool IsAllowedPrimitiveConversion(Type source, Type target) - { - // we need to check for primitives, because GetTypeCode will return the underlying type for enums - if (!source.IsPrimitive || !target.IsPrimitive) - { - return false; - } - TypeCode sourceType = Type.GetTypeCode(source); - TypeCode targetType = Type.GetTypeCode(target); - switch (sourceType) - { - case TypeCode.Char: - switch (targetType) - { - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.Int32: - case TypeCode.UInt64: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.Byte: - switch (targetType) - { - case TypeCode.Char: - case TypeCode.UInt16: - case TypeCode.Int16: - case TypeCode.UInt32: - case TypeCode.Int32: - case TypeCode.UInt64: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.SByte: - switch (targetType) - { - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.UInt16: - switch (targetType) - { - case TypeCode.UInt32: - case TypeCode.Int32: - case TypeCode.UInt64: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.Int16: - switch (targetType) - { - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.UInt32: - switch (targetType) - { - case TypeCode.UInt64: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.Int32: - switch (targetType) - { - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.UInt64: - switch (targetType) - { - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.Int64: - switch (targetType) - { - case TypeCode.Single: - case TypeCode.Double: - return true; - default: - return false; - } - case TypeCode.Single: - switch (targetType) - { - case TypeCode.Double: - return true; - default: - return false; - } - default: - return false; - } - } - - public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) - { - int matchCount = 0; - foreach (PropertyInfo property in match) - { - if (indexes == null || MatchParameterTypes(property.GetIndexParameters(), indexes)) - { - if (returnType != null) - { - if (property.PropertyType.IsPrimitive) - { - if (!IsAllowedPrimitiveConversion(returnType, property.PropertyType)) - { - continue; - } - } - else - { - if (!property.PropertyType.IsAssignableFrom(returnType)) - { - continue; - } - } - } - match[matchCount++] = property; - } - } - - if (matchCount == 0) - { - return null; - } - - if (matchCount == 1) - { - return match[0]; - } - - PropertyInfo bestMatch = match[0]; - bool ambiguous = false; - for (int i = 1; i < matchCount; i++) - { - int best = MatchTypes(bestMatch.PropertyType, match[i].PropertyType, returnType); - if (best == 0 && indexes != null) - { - best = MatchSignatures(bestMatch.PropertySignature, match[i].PropertySignature, indexes); - } - if (best == 0) - { - int depth1 = GetInheritanceDepth(bestMatch.DeclaringType); - int depth2 = GetInheritanceDepth(match[i].DeclaringType); - if (bestMatch.Name == match[i].Name && depth1 != depth2) - { - if (depth1 > depth2) - { - best = 1; - } - else - { - best = 2; - } - } - else - { - ambiguous = true; - } - } - if (best == 2) - { - ambiguous = false; - bestMatch = match[i]; - } - } - if (ambiguous) - { - throw new AmbiguousMatchException(); - } - return bestMatch; - } - } -} diff --git a/mcs/class/IKVM.Reflection/ConstructorInfo.cs b/mcs/class/IKVM.Reflection/ConstructorInfo.cs deleted file mode 100644 index 11d18a7a843..00000000000 --- a/mcs/class/IKVM.Reflection/ConstructorInfo.cs +++ /dev/null @@ -1,239 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace IKVM.Reflection -{ - public abstract class ConstructorInfo : MethodBase - { - // prevent external subclasses - internal ConstructorInfo() - { - } - - public sealed override string ToString() - { - return GetMethodInfo().ToString(); - } - - public static readonly string ConstructorName = ".ctor"; - public static readonly string TypeConstructorName = ".cctor"; - - internal abstract MethodInfo GetMethodInfo(); - - internal override MethodBase BindTypeParameters(Type type) - { - return new ConstructorInfoImpl((MethodInfo)GetMethodInfo().BindTypeParameters(type)); - } - - public sealed override MethodBase __GetMethodOnTypeDefinition() - { - return new ConstructorInfoImpl((MethodInfo)GetMethodInfo().__GetMethodOnTypeDefinition()); - } - - public sealed override MemberTypes MemberType - { - get { return MemberTypes.Constructor; } - } - - public sealed override int __MethodRVA - { - get { return GetMethodInfo().__MethodRVA; } - } - - public sealed override bool ContainsGenericParameters - { - get { return GetMethodInfo().ContainsGenericParameters; } - } - - public ParameterInfo __ReturnParameter - { - get { return new ParameterInfoWrapper(this, GetMethodInfo().ReturnParameter); } - } - - public sealed override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameters = GetMethodInfo().GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoWrapper(this, parameters[i]); - } - return parameters; - } - - public sealed override CallingConventions CallingConvention - { - get { return GetMethodInfo().CallingConvention; } - } - - public sealed override MethodAttributes Attributes - { - get { return GetMethodInfo().Attributes; } - } - - public sealed override MethodImplAttributes GetMethodImplementationFlags() - { - return GetMethodInfo().GetMethodImplementationFlags(); - } - - public sealed override Type DeclaringType - { - get { return GetMethodInfo().DeclaringType; } - } - - public sealed override string Name - { - get { return GetMethodInfo().Name; } - } - - public sealed override int MetadataToken - { - get { return GetMethodInfo().MetadataToken; } - } - - public sealed override Module Module - { - get { return GetMethodInfo().Module; } - } - - public sealed override MethodBody GetMethodBody() - { - return GetMethodInfo().GetMethodBody(); - } - - public sealed override bool __IsMissing - { - get { return GetMethodInfo().__IsMissing; } - } - - internal sealed override int ParameterCount - { - get { return GetMethodInfo().ParameterCount; } - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - return new ConstructorInfoWithReflectedType(type, this); - } - - internal sealed override int GetCurrentToken() - { - return GetMethodInfo().GetCurrentToken(); - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - return GetMethodInfo().GetPseudoCustomAttributes(attributeType); - } - - internal sealed override bool IsBaked - { - get { return GetMethodInfo().IsBaked; } - } - - internal sealed override MethodSignature MethodSignature - { - get { return GetMethodInfo().MethodSignature; } - } - - internal sealed override int ImportTo(Emit.ModuleBuilder module) - { - return GetMethodInfo().ImportTo(module); - } - } - - sealed class ConstructorInfoImpl : ConstructorInfo - { - private readonly MethodInfo method; - - internal ConstructorInfoImpl(MethodInfo method) - { - this.method = method; - } - - public override bool Equals(object obj) - { - ConstructorInfoImpl other = obj as ConstructorInfoImpl; - return other != null && other.method.Equals(method); - } - - public override int GetHashCode() - { - return method.GetHashCode(); - } - - internal override MethodInfo GetMethodInfo() - { - return method; - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return method.GetMethodOnTypeDefinition(); - } - } - - sealed class ConstructorInfoWithReflectedType : ConstructorInfo - { - private readonly Type reflectedType; - private readonly ConstructorInfo ctor; - - internal ConstructorInfoWithReflectedType(Type reflectedType, ConstructorInfo ctor) - { - Debug.Assert(reflectedType != ctor.DeclaringType); - this.reflectedType = reflectedType; - this.ctor = ctor; - } - - public override bool Equals(object obj) - { - ConstructorInfoWithReflectedType other = obj as ConstructorInfoWithReflectedType; - return other != null - && other.reflectedType == reflectedType - && other.ctor == ctor; - } - - public override int GetHashCode() - { - return reflectedType.GetHashCode() ^ ctor.GetHashCode(); - } - - public override Type ReflectedType - { - get { return reflectedType; } - } - - internal override MethodInfo GetMethodInfo() - { - return ctor.GetMethodInfo(); - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return ctor.GetMethodOnTypeDefinition(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/CustomAttributeData.cs b/mcs/class/IKVM.Reflection/CustomAttributeData.cs deleted file mode 100644 index 72026fb9b4d..00000000000 --- a/mcs/class/IKVM.Reflection/CustomAttributeData.cs +++ /dev/null @@ -1,1016 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection -{ - public sealed class CustomAttributeData - { - internal static readonly IList EmptyList = new List(0).AsReadOnly(); - - /* - * There are several states a CustomAttributeData object can be in: - * - * 1) Unresolved Custom Attribute - * - customAttributeIndex >= 0 - * - declSecurityIndex == -1 - * - declSecurityBlob == null - * - lazyConstructor = null - * - lazyConstructorArguments = null - * - lazyNamedArguments = null - * - * 2) Resolved Custom Attribute - * - customAttributeIndex >= 0 - * - declSecurityIndex == -1 - * - declSecurityBlob == null - * - lazyConstructor != null - * - lazyConstructorArguments != null - * - lazyNamedArguments != null - * - * 3) Pre-resolved Custom Attribute - * - customAttributeIndex = -1 - * - declSecurityIndex == -1 - * - declSecurityBlob == null - * - lazyConstructor != null - * - lazyConstructorArguments != null - * - lazyNamedArguments != null - * - * 4) Pseudo Custom Attribute, .NET 1.x declarative security or result of CustomAttributeBuilder.ToData() - * - customAttributeIndex = -1 - * - declSecurityIndex == -1 - * - declSecurityBlob == null - * - lazyConstructor != null - * - lazyConstructorArguments != null - * - lazyNamedArguments != null - * - * 5) Unresolved declarative security - * - customAttributeIndex = -1 - * - declSecurityIndex >= 0 - * - declSecurityBlob != null - * - lazyConstructor != null - * - lazyConstructorArguments != null - * - lazyNamedArguments == null - * - * 6) Resolved declarative security - * - customAttributeIndex = -1 - * - declSecurityIndex >= 0 - * - declSecurityBlob == null - * - lazyConstructor != null - * - lazyConstructorArguments != null - * - lazyNamedArguments != null - * - */ - private readonly Module module; - private readonly int customAttributeIndex; - private readonly int declSecurityIndex; - private readonly byte[] declSecurityBlob; - private ConstructorInfo lazyConstructor; - private IList lazyConstructorArguments; - private IList lazyNamedArguments; - - // 1) Unresolved Custom Attribute - internal CustomAttributeData(Module module, int index) - { - this.module = module; - this.customAttributeIndex = index; - this.declSecurityIndex = -1; - } - - // 4) Pseudo Custom Attribute, .NET 1.x declarative security - internal CustomAttributeData(Module module, ConstructorInfo constructor, object[] args, List namedArguments) - : this(module, constructor, WrapConstructorArgs(args, constructor.MethodSignature), namedArguments) - { - } - - private static List WrapConstructorArgs(object[] args, MethodSignature sig) - { - List list = new List(); - for (int i = 0; i < args.Length; i++) - { - list.Add(new CustomAttributeTypedArgument(sig.GetParameterType(i), args[i])); - } - return list; - } - - // 4) Pseudo Custom Attribute, .NET 1.x declarative security or result of CustomAttributeBuilder.ToData() - internal CustomAttributeData(Module module, ConstructorInfo constructor, List constructorArgs, List namedArguments) - { - this.module = module; - this.customAttributeIndex = -1; - this.declSecurityIndex = -1; - this.lazyConstructor = constructor; - lazyConstructorArguments = constructorArgs.AsReadOnly(); - if (namedArguments == null) - { - this.lazyNamedArguments = Empty.Array; - } - else - { - this.lazyNamedArguments = namedArguments.AsReadOnly(); - } - } - - // 3) Pre-resolved Custom Attribute - internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br) - { - this.module = asm.ManifestModule; - this.customAttributeIndex = -1; - this.declSecurityIndex = -1; - this.lazyConstructor = constructor; - if (br.Length == 0) - { - // it's legal to have an empty blob - lazyConstructorArguments = Empty.Array; - lazyNamedArguments = Empty.Array; - } - else - { - if (br.ReadUInt16() != 1) - { - throw new BadImageFormatException(); - } - lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor); - lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType); - } - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.Append('['); - sb.Append(Constructor.DeclaringType.FullName); - sb.Append('('); - string sep = ""; - ParameterInfo[] parameters = Constructor.GetParameters(); - IList args = ConstructorArguments; - for (int i = 0; i < parameters.Length; i++) - { - sb.Append(sep); - sep = ", "; - AppendValue(sb, parameters[i].ParameterType, args[i]); - } - foreach (CustomAttributeNamedArgument named in NamedArguments) - { - sb.Append(sep); - sep = ", "; - sb.Append(named.MemberInfo.Name); - sb.Append(" = "); - FieldInfo fi = named.MemberInfo as FieldInfo; - Type type = fi != null ? fi.FieldType : ((PropertyInfo)named.MemberInfo).PropertyType; - AppendValue(sb, type, named.TypedValue); - } - sb.Append(')'); - sb.Append(']'); - return sb.ToString(); - } - - private static void AppendValue(StringBuilder sb, Type type, CustomAttributeTypedArgument arg) - { - if (arg.ArgumentType == arg.ArgumentType.Module.universe.System_String) - { - sb.Append('"').Append(arg.Value).Append('"'); - } - else if (arg.ArgumentType.IsArray) - { - Type elementType = arg.ArgumentType.GetElementType(); - string elementTypeName; - if (elementType.IsPrimitive - || elementType == type.Module.universe.System_Object - || elementType == type.Module.universe.System_String - || elementType == type.Module.universe.System_Type) - { - elementTypeName = elementType.Name; - } - else - { - elementTypeName = elementType.FullName; - } - sb.Append("new ").Append(elementTypeName).Append("[").Append(((Array)arg.Value).Length).Append("] { "); - string sep = ""; - foreach (CustomAttributeTypedArgument elem in (CustomAttributeTypedArgument[])arg.Value) - { - sb.Append(sep); - sep = ", "; - AppendValue(sb, elementType, elem); - } - sb.Append(" }"); - } - else - { - if (arg.ArgumentType != type || (type.IsEnum && !arg.Value.Equals(0))) - { - sb.Append('('); - sb.Append(arg.ArgumentType.FullName); - sb.Append(')'); - } - sb.Append(arg.Value); - } - } - - internal static void ReadDeclarativeSecurity(Module module, int index, List list) - { - Universe u = module.universe; - Assembly asm = module.Assembly; - int action = module.DeclSecurity.records[index].Action; - ByteReader br = module.GetBlob(module.DeclSecurity.records[index].PermissionSet); - if (br.PeekByte() == '.') - { - br.ReadByte(); - int count = br.ReadCompressedInt(); - for (int j = 0; j < count; j++) - { - Type type = ReadType(asm, br); - ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction); - // LAMESPEC there is an additional length here (probably of the named argument list) - byte[] blob = br.ReadBytes(br.ReadCompressedInt()); - list.Add(new CustomAttributeData(asm, constructor, action, blob, index)); - } - } - else - { - // .NET 1.x format (xml) - char[] buf = new char[br.Length / 2]; - for (int i = 0; i < buf.Length; i++) - { - buf[i] = br.ReadChar(); - } - string xml = new String(buf); - ConstructorInfo constructor = u.System_Security_Permissions_PermissionSetAttribute.GetPseudoCustomAttributeConstructor(u.System_Security_Permissions_SecurityAction); - List args = new List(); - args.Add(new CustomAttributeNamedArgument(GetProperty(u.System_Security_Permissions_PermissionSetAttribute, "XML", u.System_String), - new CustomAttributeTypedArgument(u.System_String, xml))); - list.Add(new CustomAttributeData(asm.ManifestModule, constructor, new object[] { action }, args)); - } - } - - // 5) Unresolved declarative security - internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, int securityAction, byte[] blob, int index) - { - this.module = asm.ManifestModule; - this.customAttributeIndex = -1; - this.declSecurityIndex = index; - Universe u = constructor.Module.universe; - this.lazyConstructor = constructor; - List list = new List(); - list.Add(new CustomAttributeTypedArgument(u.System_Security_Permissions_SecurityAction, securityAction)); - this.lazyConstructorArguments = list.AsReadOnly(); - this.declSecurityBlob = blob; - } - - private static Type ReadFieldOrPropType(Assembly asm, ByteReader br) - { - Universe u = asm.universe; - switch (br.ReadByte()) - { - case Signature.ELEMENT_TYPE_BOOLEAN: - return u.System_Boolean; - case Signature.ELEMENT_TYPE_CHAR: - return u.System_Char; - case Signature.ELEMENT_TYPE_I1: - return u.System_SByte; - case Signature.ELEMENT_TYPE_U1: - return u.System_Byte; - case Signature.ELEMENT_TYPE_I2: - return u.System_Int16; - case Signature.ELEMENT_TYPE_U2: - return u.System_UInt16; - case Signature.ELEMENT_TYPE_I4: - return u.System_Int32; - case Signature.ELEMENT_TYPE_U4: - return u.System_UInt32; - case Signature.ELEMENT_TYPE_I8: - return u.System_Int64; - case Signature.ELEMENT_TYPE_U8: - return u.System_UInt64; - case Signature.ELEMENT_TYPE_R4: - return u.System_Single; - case Signature.ELEMENT_TYPE_R8: - return u.System_Double; - case Signature.ELEMENT_TYPE_STRING: - return u.System_String; - case Signature.ELEMENT_TYPE_SZARRAY: - return ReadFieldOrPropType(asm, br).MakeArrayType(); - case 0x55: - return ReadType(asm, br); - case 0x50: - return u.System_Type; - case 0x51: - return u.System_Object; - default: - throw new BadImageFormatException(); - } - } - - private static CustomAttributeTypedArgument ReadFixedArg(Assembly asm, ByteReader br, Type type) - { - Universe u = asm.universe; - if (type == u.System_String) - { - return new CustomAttributeTypedArgument(type, br.ReadString()); - } - else if (type == u.System_Boolean) - { - return new CustomAttributeTypedArgument(type, br.ReadByte() != 0); - } - else if (type == u.System_Char) - { - return new CustomAttributeTypedArgument(type, br.ReadChar()); - } - else if (type == u.System_Single) - { - return new CustomAttributeTypedArgument(type, br.ReadSingle()); - } - else if (type == u.System_Double) - { - return new CustomAttributeTypedArgument(type, br.ReadDouble()); - } - else if (type == u.System_SByte) - { - return new CustomAttributeTypedArgument(type, br.ReadSByte()); - } - else if (type == u.System_Int16) - { - return new CustomAttributeTypedArgument(type, br.ReadInt16()); - } - else if (type == u.System_Int32) - { - return new CustomAttributeTypedArgument(type, br.ReadInt32()); - } - else if (type == u.System_Int64) - { - return new CustomAttributeTypedArgument(type, br.ReadInt64()); - } - else if (type == u.System_Byte) - { - return new CustomAttributeTypedArgument(type, br.ReadByte()); - } - else if (type == u.System_UInt16) - { - return new CustomAttributeTypedArgument(type, br.ReadUInt16()); - } - else if (type == u.System_UInt32) - { - return new CustomAttributeTypedArgument(type, br.ReadUInt32()); - } - else if (type == u.System_UInt64) - { - return new CustomAttributeTypedArgument(type, br.ReadUInt64()); - } - else if (type == u.System_Type) - { - return new CustomAttributeTypedArgument(type, ReadType(asm, br)); - } - else if (type == u.System_Object) - { - return ReadFixedArg(asm, br, ReadFieldOrPropType(asm, br)); - } - else if (type.IsArray) - { - int length = br.ReadInt32(); - if (length == -1) - { - return new CustomAttributeTypedArgument(type, null); - } - Type elementType = type.GetElementType(); - CustomAttributeTypedArgument[] array = new CustomAttributeTypedArgument[length]; - for (int i = 0; i < length; i++) - { - array[i] = ReadFixedArg(asm, br, elementType); - } - return new CustomAttributeTypedArgument(type, array); - } - else if (type.IsEnum) - { - return new CustomAttributeTypedArgument(type, ReadFixedArg(asm, br, type.GetEnumUnderlyingTypeImpl()).Value); - } - else - { - throw new InvalidOperationException(); - } - } - - private static Type ReadType(Assembly asm, ByteReader br) - { - string typeName = br.ReadString(); - if (typeName == null) - { - return null; - } - if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0) - { - // there are broken compilers that emit an extra NUL character after the type name - typeName = typeName.Substring(0, typeName.Length - 1); - } - return TypeNameParser.Parse(typeName, true).GetType(asm.universe, asm, true, typeName, true, false); - } - - private static IList ReadConstructorArguments(Assembly asm, ByteReader br, ConstructorInfo constructor) - { - MethodSignature sig = constructor.MethodSignature; - int count = sig.GetParameterCount(); - List list = new List(count); - for (int i = 0; i < count; i++) - { - list.Add(ReadFixedArg(asm, br, sig.GetParameterType(i))); - } - return list.AsReadOnly(); - } - - private static IList ReadNamedArguments(Assembly asm, ByteReader br, int named, Type type) - { - List list = new List(named); - for (int i = 0; i < named; i++) - { - byte fieldOrProperty = br.ReadByte(); - Type fieldOrPropertyType = ReadFieldOrPropType(asm, br); - string name = br.ReadString(); - CustomAttributeTypedArgument value = ReadFixedArg(asm, br, fieldOrPropertyType); - MemberInfo member; - switch (fieldOrProperty) - { - case 0x53: - member = GetField(type, name, fieldOrPropertyType); - break; - case 0x54: - member = GetProperty(type, name, fieldOrPropertyType); - break; - default: - throw new BadImageFormatException(); - } - list.Add(new CustomAttributeNamedArgument(member, value)); - } - return list.AsReadOnly(); - } - - private static FieldInfo GetField(Type type, string name, Type fieldType) - { - Type org = type; - for (; type != null && !type.__IsMissing; type = type.BaseType) - { - foreach (FieldInfo field in type.__GetDeclaredFields()) - { - if (field.IsPublic && !field.IsStatic && field.Name == name) - { - return field; - } - } - } - // if the field is missing, we stick the missing field on the first missing base type - if (type == null) - { - type = org; - } - FieldSignature sig = FieldSignature.Create(fieldType, new CustomModifiers()); - return type.FindField(name, sig) - ?? type.Module.universe.GetMissingFieldOrThrow(type, name, sig); - } - - private static PropertyInfo GetProperty(Type type, string name, Type propertyType) - { - Type org = type; - for (; type != null && !type.__IsMissing; type = type.BaseType) - { - foreach (PropertyInfo property in type.__GetDeclaredProperties()) - { - if (property.IsPublic && !property.IsStatic && property.Name == name) - { - return property; - } - } - } - // if the property is missing, we stick the missing property on the first missing base type - if (type == null) - { - type = org; - } - return type.Module.universe.GetMissingPropertyOrThrow(type, name, PropertySignature.Create(CallingConventions.Standard | CallingConventions.HasThis, propertyType, null, new PackedCustomModifiers())); - } - - [Obsolete("Use AttributeType property instead.")] - internal bool __TryReadTypeName(out string ns, out string name) - { - if (Constructor.DeclaringType.IsNested) - { - ns = null; - name = null; - return false; - } - ns = Constructor.DeclaringType.__Namespace; - name = Constructor.DeclaringType.__Name; - return true; - } - - public byte[] __GetBlob() - { - if (declSecurityBlob != null) - { - return (byte[])declSecurityBlob.Clone(); - } - else if (customAttributeIndex == -1) - { - return __ToBuilder().GetBlob(module.Assembly); - } - else - { - return ((ModuleReader)module).GetBlobCopy(module.CustomAttribute.records[customAttributeIndex].Value); - } - } - - public int __Parent - { - get - { - return customAttributeIndex >= 0 - ? module.CustomAttribute.records[customAttributeIndex].Parent - : declSecurityIndex >= 0 - ? module.DeclSecurity.records[declSecurityIndex].Parent - : 0; - } - } - - // .NET 4.5 API - public Type AttributeType - { - get { return Constructor.DeclaringType; } - } - - public ConstructorInfo Constructor - { - get - { - if (lazyConstructor == null) - { - lazyConstructor = (ConstructorInfo)module.ResolveMethod(module.CustomAttribute.records[customAttributeIndex].Type); - } - return lazyConstructor; - } - } - - public IList ConstructorArguments - { - get - { - if (lazyConstructorArguments == null) - { - LazyParseArguments(); - } - return lazyConstructorArguments; - } - } - - public IList NamedArguments - { - get - { - if (lazyNamedArguments == null) - { - if (customAttributeIndex >= 0) - { - // 1) Unresolved Custom Attribute - LazyParseArguments(); - } - else - { - // 5) Unresolved declarative security - ByteReader br = new ByteReader(declSecurityBlob, 0, declSecurityBlob.Length); - // LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes) - lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadCompressedInt(), Constructor.DeclaringType); - } - } - return lazyNamedArguments; - } - } - - private void LazyParseArguments() - { - ByteReader br = module.GetBlob(module.CustomAttribute.records[customAttributeIndex].Value); - if (br.Length == 0) - { - // it's legal to have an empty blob - lazyConstructorArguments = Empty.Array; - lazyNamedArguments = Empty.Array; - } - else - { - if (br.ReadUInt16() != 1) - { - throw new BadImageFormatException(); - } - lazyConstructorArguments = ReadConstructorArguments(module.Assembly, br, Constructor); - lazyNamedArguments = ReadNamedArguments(module.Assembly, br, br.ReadUInt16(), Constructor.DeclaringType); - } - } - - public CustomAttributeBuilder __ToBuilder() - { - ParameterInfo[] parameters = Constructor.GetParameters(); - object[] args = new object[ConstructorArguments.Count]; - for (int i = 0; i < args.Length; i++) - { - args[i] = RewrapArray(parameters[i].ParameterType, ConstructorArguments[i]); - } - List namedProperties = new List(); - List propertyValues = new List(); - List namedFields = new List(); - List fieldValues = new List(); - foreach (CustomAttributeNamedArgument named in NamedArguments) - { - PropertyInfo pi = named.MemberInfo as PropertyInfo; - if (pi != null) - { - namedProperties.Add(pi); - propertyValues.Add(RewrapArray(pi.PropertyType, named.TypedValue)); - } - else - { - FieldInfo fi = (FieldInfo)named.MemberInfo; - namedFields.Add(fi); - fieldValues.Add(RewrapArray(fi.FieldType, named.TypedValue)); - } - } - return new CustomAttributeBuilder(Constructor, args, namedProperties.ToArray(), propertyValues.ToArray(), namedFields.ToArray(), fieldValues.ToArray()); - } - - private static object RewrapArray(Type type, CustomAttributeTypedArgument arg) - { - IList list = arg.Value as IList; - if (list != null) - { - Type elementType = arg.ArgumentType.GetElementType(); - object[] arr = new object[list.Count]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = RewrapArray(elementType, list[i]); - } - if (type == type.Module.universe.System_Object) - { - return CustomAttributeBuilder.__MakeTypedArgument(arg.ArgumentType, arr); - } - return arr; - } - else - { - return arg.Value; - } - } - - public static IList GetCustomAttributes(MemberInfo member) - { - return __GetCustomAttributes(member, null, false); - } - - public static IList GetCustomAttributes(Assembly assembly) - { - return assembly.GetCustomAttributesData(null); - } - - public static IList GetCustomAttributes(Module module) - { - return __GetCustomAttributes(module, null, false); - } - - public static IList GetCustomAttributes(ParameterInfo parameter) - { - return __GetCustomAttributes(parameter, null, false); - } - - public static IList __GetCustomAttributes(Assembly assembly, Type attributeType, bool inherit) - { - return assembly.GetCustomAttributesData(attributeType); - } - - public static IList __GetCustomAttributes(Module module, Type attributeType, bool inherit) - { - if (module.__IsMissing) - { - throw new MissingModuleException((MissingModule)module); - } - return GetCustomAttributesImpl(null, module, 0x00000001, attributeType) ?? EmptyList; - } - - public static IList __GetCustomAttributes(ParameterInfo parameter, Type attributeType, bool inherit) - { - Module module = parameter.Module; - List list = null; - if (module.universe.ReturnPseudoCustomAttributes) - { - if (attributeType == null || attributeType.IsAssignableFrom(parameter.Module.universe.System_Runtime_InteropServices_MarshalAsAttribute)) - { - FieldMarshal spec; - if (parameter.__TryGetFieldMarshal(out spec)) - { - if (list == null) - { - list = new List(); - } - list.Add(CustomAttributeData.CreateMarshalAsPseudoCustomAttribute(parameter.Module, spec)); - } - } - } - ModuleBuilder mb = module as ModuleBuilder; - int token = parameter.MetadataToken; - if (mb != null && mb.IsSaved && mb.IsPseudoToken(token)) - { - token = mb.ResolvePseudoToken(token); - } - return GetCustomAttributesImpl(list, module, token, attributeType) ?? EmptyList; - } - - public static IList __GetCustomAttributes(MemberInfo member, Type attributeType, bool inherit) - { - if (!member.IsBaked) - { - // like .NET we we don't return custom attributes for unbaked members - throw new NotImplementedException(); - } - if (!inherit || !IsInheritableAttribute(attributeType)) - { - return GetCustomAttributesImpl(null, member, attributeType) ?? EmptyList; - } - List list = new List(); - for (; ; ) - { - GetCustomAttributesImpl(list, member, attributeType); - Type type = member as Type; - if (type != null) - { - type = type.BaseType; - if (type == null) - { - return list; - } - member = type; - continue; - } - MethodInfo method = member as MethodInfo; - if (method != null) - { - MemberInfo prev = member; - method = method.GetBaseDefinition(); - if (method == null || method == prev) - { - return list; - } - member = method; - continue; - } - return list; - } - } - - private static List GetCustomAttributesImpl(List list, MemberInfo member, Type attributeType) - { - if (member.Module.universe.ReturnPseudoCustomAttributes) - { - List pseudo = member.GetPseudoCustomAttributes(attributeType); - if (list == null) - { - list = pseudo; - } - else if (pseudo != null) - { - list.AddRange(pseudo); - } - } - return GetCustomAttributesImpl(list, member.Module, member.GetCurrentToken(), attributeType); - } - - internal static List GetCustomAttributesImpl(List list, Module module, int token, Type attributeType) - { - foreach (int i in module.CustomAttribute.Filter(token)) - { - if (attributeType == null) - { - if (list == null) - { - list = new List(); - } - list.Add(new CustomAttributeData(module, i)); - } - else - { - if (attributeType.IsAssignableFrom(module.ResolveMethod(module.CustomAttribute.records[i].Type).DeclaringType)) - { - if (list == null) - { - list = new List(); - } - list.Add(new CustomAttributeData(module, i)); - } - } - } - return list; - } - - public static IList __GetCustomAttributes(Type type, Type interfaceType, Type attributeType, bool inherit) - { - Module module = type.Module; - foreach (int i in module.InterfaceImpl.Filter(type.MetadataToken)) - { - if (module.ResolveType(module.InterfaceImpl.records[i].Interface, type) == interfaceType) - { - return GetCustomAttributesImpl(null, module, (InterfaceImplTable.Index << 24) | (i + 1), attributeType) ?? EmptyList; - } - } - return EmptyList; - } - - public static IList __GetDeclarativeSecurity(Assembly assembly) - { - if (assembly.__IsMissing) - { - throw new MissingAssemblyException((MissingAssembly)assembly); - } - return assembly.ManifestModule.GetDeclarativeSecurity(0x20000001); - } - - public static IList __GetDeclarativeSecurity(Type type) - { - if ((type.Attributes & TypeAttributes.HasSecurity) != 0) - { - return type.Module.GetDeclarativeSecurity(type.MetadataToken); - } - else - { - return EmptyList; - } - } - - public static IList __GetDeclarativeSecurity(MethodBase method) - { - if ((method.Attributes & MethodAttributes.HasSecurity) != 0) - { - return method.Module.GetDeclarativeSecurity(method.MetadataToken); - } - else - { - return EmptyList; - } - } - - private static bool IsInheritableAttribute(Type attribute) - { - Type attributeUsageAttribute = attribute.Module.universe.System_AttributeUsageAttribute; - IList attr = __GetCustomAttributes(attribute, attributeUsageAttribute, false); - if (attr.Count != 0) - { - foreach (CustomAttributeNamedArgument named in attr[0].NamedArguments) - { - if (named.MemberInfo.Name == "Inherited") - { - return (bool)named.TypedValue.Value; - } - } - } - return true; - } - - internal static CustomAttributeData CreateDllImportPseudoCustomAttribute(Module module, ImplMapFlags flags, string entryPoint, string dllName, MethodImplAttributes attr) - { - Type type = module.universe.System_Runtime_InteropServices_DllImportAttribute; - ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_String); - List list = new List(); - System.Runtime.InteropServices.CharSet charSet; - switch (flags & ImplMapFlags.CharSetMask) - { - case ImplMapFlags.CharSetAnsi: - charSet = System.Runtime.InteropServices.CharSet.Ansi; - break; - case ImplMapFlags.CharSetUnicode: - charSet = System.Runtime.InteropServices.CharSet.Unicode; - break; - case ImplMapFlags.CharSetAuto: - charSet = System.Runtime.InteropServices.CharSet.Auto; - break; - case ImplMapFlags.CharSetNotSpec: - default: - charSet = System.Runtime.InteropServices.CharSet.None; - break; - } - System.Runtime.InteropServices.CallingConvention callingConvention; - switch (flags & ImplMapFlags.CallConvMask) - { - case ImplMapFlags.CallConvCdecl: - callingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl; - break; - case ImplMapFlags.CallConvFastcall: - callingConvention = System.Runtime.InteropServices.CallingConvention.FastCall; - break; - case ImplMapFlags.CallConvStdcall: - callingConvention = System.Runtime.InteropServices.CallingConvention.StdCall; - break; - case ImplMapFlags.CallConvThiscall: - callingConvention = System.Runtime.InteropServices.CallingConvention.ThisCall; - break; - case ImplMapFlags.CallConvWinapi: - callingConvention = System.Runtime.InteropServices.CallingConvention.Winapi; - break; - default: - callingConvention = 0; - break; - } - AddNamedArgument(list, type, "EntryPoint", entryPoint); - AddNamedArgument(list, type, "CharSet", module.universe.System_Runtime_InteropServices_CharSet, (int)charSet); - AddNamedArgument(list, type, "ExactSpelling", (int)flags, (int)ImplMapFlags.NoMangle); - AddNamedArgument(list, type, "SetLastError", (int)flags, (int)ImplMapFlags.SupportsLastError); - AddNamedArgument(list, type, "PreserveSig", (int)attr, (int)MethodImplAttributes.PreserveSig); - AddNamedArgument(list, type, "CallingConvention", module.universe.System_Runtime_InteropServices_CallingConvention, (int)callingConvention); - AddNamedArgument(list, type, "BestFitMapping", (int)flags, (int)ImplMapFlags.BestFitOn); - AddNamedArgument(list, type, "ThrowOnUnmappableChar", (int)flags, (int)ImplMapFlags.CharMapErrorOn); - return new CustomAttributeData(module, constructor, new object[] { dllName }, list); - } - - internal static CustomAttributeData CreateMarshalAsPseudoCustomAttribute(Module module, FieldMarshal fm) - { - Type typeofMarshalAs = module.universe.System_Runtime_InteropServices_MarshalAsAttribute; - Type typeofUnmanagedType = module.universe.System_Runtime_InteropServices_UnmanagedType; - Type typeofVarEnum = module.universe.System_Runtime_InteropServices_VarEnum; - Type typeofType = module.universe.System_Type; - List named = new List(); - AddNamedArgument(named, typeofMarshalAs, "ArraySubType", typeofUnmanagedType, (int)(fm.ArraySubType ?? 0)); - AddNamedArgument(named, typeofMarshalAs, "SizeParamIndex", module.universe.System_Int16, fm.SizeParamIndex ?? 0); - AddNamedArgument(named, typeofMarshalAs, "SizeConst", module.universe.System_Int32, fm.SizeConst ?? 0); - AddNamedArgument(named, typeofMarshalAs, "IidParameterIndex", module.universe.System_Int32, fm.IidParameterIndex ?? 0); - AddNamedArgument(named, typeofMarshalAs, "SafeArraySubType", typeofVarEnum, (int)(fm.SafeArraySubType ?? 0)); - if (fm.SafeArrayUserDefinedSubType != null) - { - AddNamedArgument(named, typeofMarshalAs, "SafeArrayUserDefinedSubType", typeofType, fm.SafeArrayUserDefinedSubType); - } - if (fm.MarshalType != null) - { - AddNamedArgument(named, typeofMarshalAs, "MarshalType", module.universe.System_String, fm.MarshalType); - } - if (fm.MarshalTypeRef != null) - { - AddNamedArgument(named, typeofMarshalAs, "MarshalTypeRef", module.universe.System_Type, fm.MarshalTypeRef); - } - if (fm.MarshalCookie != null) - { - AddNamedArgument(named, typeofMarshalAs, "MarshalCookie", module.universe.System_String, fm.MarshalCookie); - } - ConstructorInfo constructor = typeofMarshalAs.GetPseudoCustomAttributeConstructor(typeofUnmanagedType); - return new CustomAttributeData(module, constructor, new object[] { (int)fm.UnmanagedType }, named); - } - - private static void AddNamedArgument(List list, Type type, string fieldName, string value) - { - AddNamedArgument(list, type, fieldName, type.Module.universe.System_String, value); - } - - private static void AddNamedArgument(List list, Type type, string fieldName, int flags, int flagMask) - { - AddNamedArgument(list, type, fieldName, type.Module.universe.System_Boolean, (flags & flagMask) != 0); - } - - private static void AddNamedArgument(List list, Type attributeType, string fieldName, Type valueType, object value) - { - // some fields are not available on the .NET Compact Framework version of DllImportAttribute/MarshalAsAttribute - FieldInfo field = attributeType.FindField(fieldName, FieldSignature.Create(valueType, new CustomModifiers())); - if (field != null) - { - list.Add(new CustomAttributeNamedArgument(field, new CustomAttributeTypedArgument(valueType, value))); - } - } - - internal static CustomAttributeData CreateFieldOffsetPseudoCustomAttribute(Module module, int offset) - { - Type type = module.universe.System_Runtime_InteropServices_FieldOffsetAttribute; - ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(module.universe.System_Int32); - return new CustomAttributeData(module, constructor, new object[] { offset }, null); - } - - internal static CustomAttributeData CreatePreserveSigPseudoCustomAttribute(Module module) - { - Type type = module.universe.System_Runtime_InteropServices_PreserveSigAttribute; - ConstructorInfo constructor = type.GetPseudoCustomAttributeConstructor(); - return new CustomAttributeData(module, constructor, Empty.Array, null); - } - } -} diff --git a/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs b/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs deleted file mode 100644 index d9a84b7a74a..00000000000 --- a/mcs/class/IKVM.Reflection/CustomAttributeNamedArgument.cs +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ - public struct CustomAttributeNamedArgument - { - private readonly MemberInfo member; - private readonly CustomAttributeTypedArgument value; - - internal CustomAttributeNamedArgument(MemberInfo member, CustomAttributeTypedArgument value) - { - this.member = member; - this.value = value; - } - - public override bool Equals(object obj) - { - return this == obj as CustomAttributeNamedArgument?; - } - - public override int GetHashCode() - { - return member.GetHashCode() ^ 53 * value.GetHashCode(); - } - - public MemberInfo MemberInfo - { - get { return member; } - } - - public CustomAttributeTypedArgument TypedValue - { - get { return value; } - } - - public static bool operator ==(CustomAttributeNamedArgument arg1, CustomAttributeNamedArgument arg2) - { - return arg1.member.Equals(arg2.member) && arg1.value == arg2.value; - } - - public static bool operator !=(CustomAttributeNamedArgument arg1, CustomAttributeNamedArgument arg2) - { - return !(arg1 == arg2); - } - } -} diff --git a/mcs/class/IKVM.Reflection/CustomAttributeTypedArgument.cs b/mcs/class/IKVM.Reflection/CustomAttributeTypedArgument.cs deleted file mode 100644 index 3403135af7e..00000000000 --- a/mcs/class/IKVM.Reflection/CustomAttributeTypedArgument.cs +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ - public struct CustomAttributeTypedArgument - { - private readonly Type type; - private readonly object value; - - internal CustomAttributeTypedArgument(Type type, object value) - { - this.type = type; - this.value = value; - } - - public override bool Equals(object obj) - { - return this == obj as CustomAttributeTypedArgument?; - } - - public override int GetHashCode() - { - return type.GetHashCode() ^ 77 * (value == null ? 0 : value.GetHashCode()); - } - - public Type ArgumentType - { - get { return type; } - } - - public Object Value - { - get { return value; } - } - - public static bool operator ==(CustomAttributeTypedArgument arg1, CustomAttributeTypedArgument arg2) - { - return arg1.type.Equals(arg2.type) && (arg1.value == arg2.value || (arg1.value != null && arg1.value.Equals(arg2.value))); - } - - public static bool operator !=(CustomAttributeTypedArgument arg1, CustomAttributeTypedArgument arg2) - { - return !(arg1 == arg2); - } - } -} diff --git a/mcs/class/IKVM.Reflection/CustomModifiers.cs b/mcs/class/IKVM.Reflection/CustomModifiers.cs deleted file mode 100644 index e8670614e96..00000000000 --- a/mcs/class/IKVM.Reflection/CustomModifiers.cs +++ /dev/null @@ -1,352 +0,0 @@ -/* - Copyright (C) 2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - public struct CustomModifiers : IEquatable, IEnumerable - { - // note that FromReqOpt assumes that Initial == ModOpt - private static Type Initial { get { return MarkerType.ModOpt; } } - private readonly Type[] types; - - internal CustomModifiers(List list) - { - bool required = Initial == MarkerType.ModReq; - int count = list.Count; - foreach (CustomModifiersBuilder.Item item in list) - { - if (item.required != required) - { - required = item.required; - count++; - } - } - types = new Type[count]; - required = Initial == MarkerType.ModReq; - int index = 0; - foreach (CustomModifiersBuilder.Item item in list) - { - if (item.required != required) - { - required = item.required; - types[index++] = required ? MarkerType.ModReq : MarkerType.ModOpt; - } - types[index++] = item.type; - } - } - - private CustomModifiers(Type[] types) - { - Debug.Assert(types == null || types.Length != 0); - this.types = types; - } - - public struct Enumerator : IEnumerator - { - private readonly Type[] types; - private int index; - private bool required; - - internal Enumerator(Type[] types) - { - this.types = types; - this.index = -1; - this.required = Initial == MarkerType.ModReq; - } - - void System.Collections.IEnumerator.Reset() - { - this.index = -1; - this.required = Initial == MarkerType.ModReq; - } - - public Entry Current - { - get { return new Entry(types[index], required); } - } - - public bool MoveNext() - { - if (types == null || index == types.Length) - { - return false; - } - index++; - if (index == types.Length) - { - return false; - } - else if (types[index] == MarkerType.ModOpt) - { - required = false; - index++; - } - else if (types[index] == MarkerType.ModReq) - { - required = true; - index++; - } - return true; - } - - object System.Collections.IEnumerator.Current - { - get { return Current; } - } - - void IDisposable.Dispose() - { - } - } - - public struct Entry - { - private readonly Type type; - private readonly bool required; - - internal Entry(Type type, bool required) - { - this.type = type; - this.required = required; - } - - public Type Type - { - get { return type; } - } - - public bool IsRequired - { - get { return required; } - } - } - - public Enumerator GetEnumerator() - { - return new Enumerator(types); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public bool IsEmpty - { - get { return types == null; } - } - - public bool Equals(CustomModifiers other) - { - return Util.ArrayEquals(types, other.types); - } - - public override bool Equals(object obj) - { - CustomModifiers? other = obj as CustomModifiers?; - return other != null && Equals(other.Value); - } - - public override int GetHashCode() - { - return Util.GetHashCode(types); - } - - public override string ToString() - { - if (types == null) - { - return string.Empty; - } - StringBuilder sb = new StringBuilder(); - string sep = ""; - foreach (Entry e in this) - { - sb.Append(sep).Append(e.IsRequired ? "modreq(" : "modopt(").Append(e.Type.FullName).Append(')'); - sep = " "; - } - return sb.ToString(); - } - - private Type[] GetRequiredOrOptional(bool required) - { - if (types == null) - { - return Type.EmptyTypes; - } - int count = 0; - foreach (Entry e in this) - { - if (e.IsRequired == required) - { - count++; - } - } - Type[] result = new Type[count]; - foreach (Entry e in this) - { - if (e.IsRequired == required) - { - // FXBUG reflection (and ildasm) return custom modifiers in reverse order - // while SRE writes them in the specified order - result[--count] = e.Type; - } - } - return result; - } - - internal Type[] GetRequired() - { - return GetRequiredOrOptional(true); - } - - internal Type[] GetOptional() - { - return GetRequiredOrOptional(false); - } - - internal CustomModifiers Bind(IGenericBinder binder) - { - if (types == null) - { - return this; - } - Type[] result = types; - for (int i = 0; i < types.Length; i++) - { - if (types[i] == MarkerType.ModOpt || types[i] == MarkerType.ModReq) - { - continue; - } - Type type = types[i].BindTypeParameters(binder); - if (!ReferenceEquals(type, types[i])) - { - if (result == types) - { - result = (Type[])types.Clone(); - } - result[i] = type; - } - } - return new CustomModifiers(result); - } - - internal static CustomModifiers Read(ModuleReader module, ByteReader br, IGenericContext context) - { - byte b = br.PeekByte(); - if (!IsCustomModifier(b)) - { - return new CustomModifiers(); - } - List list = new List(); - Type mode = Initial; - do - { - Type cmod = br.ReadByte() == Signature.ELEMENT_TYPE_CMOD_REQD ? MarkerType.ModReq : MarkerType.ModOpt; - if (mode != cmod) - { - mode = cmod; - list.Add(mode); - } - list.Add(Signature.ReadTypeDefOrRefEncoded(module, br, context)); - b = br.PeekByte(); - } - while (IsCustomModifier(b)); - return new CustomModifiers(list.ToArray()); - } - - internal static void Skip(ByteReader br) - { - byte b = br.PeekByte(); - while (IsCustomModifier(b)) - { - br.ReadByte(); - br.ReadCompressedInt(); - b = br.PeekByte(); - } - } - - internal static CustomModifiers FromReqOpt(Type[] req, Type[] opt) - { - List list = null; - if (opt != null && opt.Length != 0) - { - Debug.Assert(Initial == MarkerType.ModOpt); - list = new List(opt); - } - if (req != null && req.Length != 0) - { - if (list == null) - { - list = new List(); - } - list.Add(MarkerType.ModReq); - list.AddRange(req); - } - if (list == null) - { - return new CustomModifiers(); - } - else - { - return new CustomModifiers(list.ToArray()); - } - } - - private static bool IsCustomModifier(byte b) - { - return b == Signature.ELEMENT_TYPE_CMOD_OPT || b == Signature.ELEMENT_TYPE_CMOD_REQD; - } - - internal static CustomModifiers Combine(CustomModifiers mods1, CustomModifiers mods2) - { - if (mods1.IsEmpty) - { - return mods2; - } - else if (mods2.IsEmpty) - { - return mods1; - } - else - { - Type[] combo = new Type[mods1.types.Length + mods2.types.Length]; - Array.Copy(mods1.types, combo, mods1.types.Length); - Array.Copy(mods2.types, 0, combo, mods1.types.Length, mods2.types.Length); - return new CustomModifiers(combo); - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs b/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs deleted file mode 100644 index ceabeac73af..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/AssemblyBuilder.cs +++ /dev/null @@ -1,812 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Configuration.Assemblies; -using System.IO; -using System.Diagnostics; -using System.Globalization; -using System.Resources; -using System.Security.Cryptography; -using System.Security; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Impl; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class AssemblyBuilder : Assembly - { - private readonly string name; - private ushort majorVersion; - private ushort minorVersion; - private ushort buildVersion; - private ushort revisionVersion; - private string culture; - private AssemblyNameFlags flags; - private AssemblyHashAlgorithm hashAlgorithm; - private StrongNameKeyPair keyPair; - private byte[] publicKey; - internal readonly string dir; - private readonly PermissionSet requiredPermissions; - private readonly PermissionSet optionalPermissions; - private readonly PermissionSet refusedPermissions; - private PEFileKinds fileKind = PEFileKinds.Dll; - private MethodInfo entryPoint; - private VersionInfo versionInfo; - private byte[] win32icon; - private byte[] win32manifest; - private byte[] win32resources; - private string imageRuntimeVersion; - internal int mdStreamVersion = 0x20000; - private Module pseudoManifestModule; - private readonly List resourceFiles = new List(); - private readonly List modules = new List(); - private readonly List addedModules = new List(); - private readonly List customAttributes = new List(); - private readonly List declarativeSecurity = new List(); - private readonly List typeForwarders = new List(); - - private struct ResourceFile - { - internal string Name; - internal string FileName; - internal ResourceAttributes Attributes; - internal ResourceWriter Writer; - } - - internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) - : base(universe) - { - this.name = name.Name; - SetVersionHelper(name.Version); - if (!string.IsNullOrEmpty(name.Culture)) - { - this.culture = name.Culture; - } - this.flags = name.RawFlags; - this.hashAlgorithm = name.HashAlgorithm; - if (this.hashAlgorithm == AssemblyHashAlgorithm.None) - { - this.hashAlgorithm = AssemblyHashAlgorithm.SHA1; - } - this.keyPair = name.KeyPair; - if (this.keyPair != null) - { - this.publicKey = this.keyPair.PublicKey; - } - else - { - byte[] publicKey = name.GetPublicKey(); - if (publicKey != null && publicKey.Length != 0) - { - this.publicKey = (byte[])publicKey.Clone(); - } - } - this.dir = dir ?? "."; - this.requiredPermissions = requiredPermissions; - this.optionalPermissions = optionalPermissions; - this.refusedPermissions = refusedPermissions; - if (universe.HasMscorlib && !universe.Mscorlib.__IsMissing && universe.Mscorlib.ImageRuntimeVersion != null) - { - this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion; - } - else - { - this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion; - } - } - - private void SetVersionHelper(Version version) - { - if (version == null) - { - majorVersion = 0; - minorVersion = 0; - buildVersion = 0; - revisionVersion = 0; - } - else - { - majorVersion = (ushort)version.Major; - minorVersion = (ushort)version.Minor; - buildVersion = version.Build == -1 ? (ushort)0 : (ushort)version.Build; - revisionVersion = version.Revision == -1 ? (ushort)0 : (ushort)version.Revision; - } - } - - private void Rename(AssemblyName oldName) - { - this.fullName = null; - universe.RenameAssembly(this, oldName); - } - - public void __SetAssemblyVersion(Version version) - { - AssemblyName oldName = GetName(); - SetVersionHelper(version); - Rename(oldName); - } - - public void __SetAssemblyCulture(string cultureName) - { - AssemblyName oldName = GetName(); - this.culture = cultureName; - Rename(oldName); - } - - public void __SetAssemblyKeyPair(StrongNameKeyPair keyPair) - { - AssemblyName oldName = GetName(); - this.keyPair = keyPair; - if (keyPair != null) - { - this.publicKey = keyPair.PublicKey; - } - Rename(oldName); - } - - // this is used in combination with delay signing - public void __SetAssemblyPublicKey(byte[] publicKey) - { - AssemblyName oldName = GetName(); - this.publicKey = publicKey == null ? null : (byte[])publicKey.Clone(); - Rename(oldName); - } - - public void __SetAssemblyAlgorithmId(AssemblyHashAlgorithm hashAlgorithm) - { - this.hashAlgorithm = hashAlgorithm; - } - - public void __SetAssemblyFlags(AssemblyNameFlags flags) - { - AssemblyName oldName = GetName(); - this.flags = flags; - Rename(oldName); - } - - public override AssemblyNameFlags __AssemblyFlags - { - get { return flags; } - } - - internal string Name - { - get { return name; } - } - - public override AssemblyName GetName() - { - AssemblyName n = new AssemblyName(); - n.Name = name; - n.Version = new Version(majorVersion, minorVersion, buildVersion, revisionVersion); - n.Culture = culture ?? ""; - n.HashAlgorithm = hashAlgorithm; - n.RawFlags = flags; - n.SetPublicKey(publicKey != null ? (byte[])publicKey.Clone() : Empty.Array); - n.KeyPair = keyPair; - return n; - } - - public override string Location - { - get { throw new NotSupportedException(); } - } - - public ModuleBuilder DefineDynamicModule(string name, string fileName) - { - return DefineDynamicModule(name, fileName, false); - } - - public ModuleBuilder DefineDynamicModule(string name, string fileName, bool emitSymbolInfo) - { - ModuleBuilder module = new ModuleBuilder(this, name, fileName, emitSymbolInfo); - modules.Add(module); - return module; - } - - public ModuleBuilder GetDynamicModule(string name) - { - foreach (ModuleBuilder module in modules) - { - if (module.Name == name) - { - return module; - } - } - return null; - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - customAttributes.Add(customBuilder); - } - - public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) - { - declarativeSecurity.Add(customBuilder); - } - - public void __AddTypeForwarder(Type type) - { - typeForwarders.Add(type); - } - - public void SetEntryPoint(MethodInfo entryMethod) - { - SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication); - } - - public void SetEntryPoint(MethodInfo entryMethod, PEFileKinds fileKind) - { - this.entryPoint = entryMethod; - this.fileKind = fileKind; - } - - public void __Save(Stream stream, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek || stream.Position != 0) - { - throw new ArgumentException("Stream must support read/write/seek and current position must be zero.", "stream"); - } - if (modules.Count != 1) - { - throw new NotSupportedException("Saving to a stream is only supported for single module assemblies."); - } - SaveImpl(modules[0].fileName, stream, portableExecutableKind, imageFileMachine); - } - - public void Save(string assemblyFileName) - { - Save(assemblyFileName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386); - } - - public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - SaveImpl(assemblyFileName, null, portableExecutableKind, imageFileMachine); - } - - private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - ModuleBuilder manifestModule = null; - - foreach (ModuleBuilder moduleBuilder in modules) - { - moduleBuilder.SetIsSaved(); - moduleBuilder.PopulatePropertyAndEventTables(); - - if (manifestModule == null - && string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0) - { - manifestModule = moduleBuilder; - } - } - - if (manifestModule == null) - { - manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false); - } - - AssemblyTable.Record assemblyRecord = new AssemblyTable.Record(); - assemblyRecord.HashAlgId = (int)hashAlgorithm; - assemblyRecord.Name = manifestModule.Strings.Add(name); - assemblyRecord.MajorVersion = majorVersion; - assemblyRecord.MinorVersion = minorVersion; - assemblyRecord.BuildNumber = buildVersion; - assemblyRecord.RevisionNumber = revisionVersion; - if (publicKey != null) - { - assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey)); - assemblyRecord.Flags = (int)(flags | AssemblyNameFlags.PublicKey); - } - else - { - assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey); - } - if (culture != null) - { - assemblyRecord.Culture = manifestModule.Strings.Add(culture); - } - int token = 0x20000000 + manifestModule.AssemblyTable.AddRecord(assemblyRecord); - -#pragma warning disable 618 - // this values are obsolete, but we already know that so we disable the warning - System.Security.Permissions.SecurityAction requestMinimum = System.Security.Permissions.SecurityAction.RequestMinimum; - System.Security.Permissions.SecurityAction requestOptional = System.Security.Permissions.SecurityAction.RequestOptional; - System.Security.Permissions.SecurityAction requestRefuse = System.Security.Permissions.SecurityAction.RequestRefuse; -#pragma warning restore 618 - if (requiredPermissions != null) - { - manifestModule.AddDeclarativeSecurity(token, requestMinimum, requiredPermissions); - } - if (optionalPermissions != null) - { - manifestModule.AddDeclarativeSecurity(token, requestOptional, optionalPermissions); - } - if (refusedPermissions != null) - { - manifestModule.AddDeclarativeSecurity(token, requestRefuse, refusedPermissions); - } - - ResourceSection unmanagedResources = versionInfo != null || win32icon != null || win32manifest != null || win32resources != null - ? new ResourceSection() - : null; - - if (versionInfo != null) - { - versionInfo.SetName(GetName()); - versionInfo.SetFileName(assemblyFileName); - foreach (CustomAttributeBuilder cab in customAttributes) - { - // .NET doesn't support copying blob custom attributes into the version info - if (!cab.HasBlob) - { - versionInfo.SetAttribute(cab); - } - } - ByteBuffer versionInfoData = new ByteBuffer(512); - versionInfo.Write(versionInfoData); - unmanagedResources.AddVersionInfo(versionInfoData); - } - - if (win32icon != null) - { - unmanagedResources.AddIcon(win32icon); - } - - if (win32manifest != null) - { - unmanagedResources.AddManifest(win32manifest, fileKind == PEFileKinds.Dll ? (ushort)2 : (ushort)1); - } - - if (win32resources != null) - { - unmanagedResources.ExtractResources(win32resources); - } - - foreach (CustomAttributeBuilder cab in customAttributes) - { - // we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET) - manifestModule.SetCustomAttribute(0x20000001, cab); - } - - manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity); - - foreach (Type type in typeForwarders) - { - manifestModule.AddTypeForwarder(type); - } - - foreach (ResourceFile resfile in resourceFiles) - { - if (resfile.Writer != null) - { - resfile.Writer.Generate(); - resfile.Writer.Close(); - } - int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/); - ManifestResourceTable.Record rec = new ManifestResourceTable.Record(); - rec.Offset = 0; - rec.Flags = (int)resfile.Attributes; - rec.Name = manifestModule.Strings.Add(resfile.Name); - rec.Implementation = fileToken; - manifestModule.ManifestResource.AddRecord(rec); - } - - int entryPointToken = 0; - - foreach (ModuleBuilder moduleBuilder in modules) - { - moduleBuilder.FillAssemblyRefTable(); - moduleBuilder.EmitResources(); - if (moduleBuilder != manifestModule) - { - int fileToken; - if (entryPoint != null && entryPoint.Module == moduleBuilder) - { - ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken); - entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/); - } - else - { - ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0); - fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/); - } - moduleBuilder.ExportTypes(fileToken, manifestModule); - } - } - - foreach (Module module in addedModules) - { - int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/); - module.ExportTypes(fileToken, manifestModule); - } - - if (entryPointToken == 0 && entryPoint != null) - { - entryPointToken = entryPoint.MetadataToken; - } - - // finally, write the manifest module - ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull); - } - - private int AddFile(ModuleBuilder manifestModule, string fileName, int flags) - { - SHA1Managed hash = new SHA1Managed(); - string fullPath = fileName; - if (dir != null) - { - fullPath = Path.Combine(dir, fileName); - } - using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read)) - { - using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write)) - { - byte[] buf = new byte[8192]; - ModuleWriter.HashChunk(fs, cs, buf, (int)fs.Length); - } - } - return manifestModule.__AddModule(flags, Path.GetFileName(fileName), hash.Hash); - } - - public void AddResourceFile(string name, string fileName) - { - AddResourceFile(name, fileName, ResourceAttributes.Public); - } - - public void AddResourceFile(string name, string fileName, ResourceAttributes attribs) - { - ResourceFile resfile = new ResourceFile(); - resfile.Name = name; - resfile.FileName = fileName; - resfile.Attributes = attribs; - resourceFiles.Add(resfile); - } - - public IResourceWriter DefineResource(string name, string description, string fileName) - { - return DefineResource(name, description, fileName, ResourceAttributes.Public); - } - - public IResourceWriter DefineResource(string name, string description, string fileName, ResourceAttributes attribute) - { - // FXBUG we ignore the description, because there is no such thing - - string fullPath = fileName; - if (dir != null) - { - fullPath = Path.Combine(dir, fileName); - } - ResourceWriter rw = new ResourceWriter(fullPath); - ResourceFile resfile; - resfile.Name = name; - resfile.FileName = fileName; - resfile.Attributes = attribute; - resfile.Writer = rw; - resourceFiles.Add(resfile); - return rw; - } - - public void DefineVersionInfoResource() - { - if (versionInfo != null || win32resources != null) - { - throw new ArgumentException("Native resource has already been defined."); - } - versionInfo = new VersionInfo(); - } - - public void DefineVersionInfoResource(string product, string productVersion, string company, string copyright, string trademark) - { - if (versionInfo != null || win32resources != null) - { - throw new ArgumentException("Native resource has already been defined."); - } - versionInfo = new VersionInfo(); - versionInfo.product = product; - versionInfo.informationalVersion = productVersion; - versionInfo.company = company; - versionInfo.copyright = copyright; - versionInfo.trademark = trademark; - } - - public void __DefineIconResource(byte[] iconFile) - { - if (win32icon != null || win32resources != null) - { - throw new ArgumentException("Native resource has already been defined."); - } - win32icon = (byte[])iconFile.Clone(); - } - - public void __DefineManifestResource(byte[] manifest) - { - if (win32manifest != null || win32resources != null) - { - throw new ArgumentException("Native resource has already been defined."); - } - win32manifest = (byte[])manifest.Clone(); - } - - public void __DefineUnmanagedResource(byte[] resource) - { - if (versionInfo != null || win32icon != null || win32manifest != null || win32resources != null) - { - throw new ArgumentException("Native resource has already been defined."); - } - // The standard .NET DefineUnmanagedResource(byte[]) is useless, because it embeds "resource" (as-is) as the .rsrc section, - // but it doesn't set the PE file Resource Directory entry to point to it. That's why we have a renamed version, which behaves - // like DefineUnmanagedResource(string). - win32resources = (byte[])resource.Clone(); - } - - public void DefineUnmanagedResource(string resourceFileName) - { - // This method reads the specified resource file (Win32 .res file) and converts it into the appropriate format and embeds it in the .rsrc section, - // also setting the Resource Directory entry. - __DefineUnmanagedResource(File.ReadAllBytes(resourceFileName)); - } - - public override Type[] GetTypes() - { - List list = new List(); - foreach (ModuleBuilder module in modules) - { - module.GetTypesImpl(list); - } - foreach (Module module in addedModules) - { - module.GetTypesImpl(list); - } - return list.ToArray(); - } - - internal override Type FindType(TypeName typeName) - { - foreach (ModuleBuilder mb in modules) - { - Type type = mb.FindType(typeName); - if (type != null) - { - return type; - } - } - foreach (Module module in addedModules) - { - Type type = module.FindType(typeName); - if (type != null) - { - return type; - } - } - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - foreach (ModuleBuilder mb in modules) - { - Type type = mb.FindTypeIgnoreCase(lowerCaseName); - if (type != null) - { - return type; - } - } - foreach (Module module in addedModules) - { - Type type = module.FindTypeIgnoreCase(lowerCaseName); - if (type != null) - { - return type; - } - } - return null; - } - - public override string ImageRuntimeVersion - { - get { return imageRuntimeVersion; } - } - - public void __SetImageRuntimeVersion(string imageRuntimeVersion, int mdStreamVersion) - { - this.imageRuntimeVersion = imageRuntimeVersion; - this.mdStreamVersion = mdStreamVersion; - } - - public override Module ManifestModule - { - get - { - if (pseudoManifestModule == null) - { - pseudoManifestModule = new ManifestModule(this); - } - return pseudoManifestModule; - } - } - - public override MethodInfo EntryPoint - { - get { return entryPoint; } - } - - public override AssemblyName[] GetReferencedAssemblies() - { - return Empty.Array; - } - - public override Module[] GetLoadedModules(bool getResourceModules) - { - return GetModules(getResourceModules); - } - - public override Module[] GetModules(bool getResourceModules) - { - List list = new List(); - foreach (ModuleBuilder module in modules) - { - if (getResourceModules || !module.IsResource()) - { - list.Add(module); - } - } - foreach (Module module in addedModules) - { - if (getResourceModules || !module.IsResource()) - { - list.Add(module); - } - } - return list.ToArray(); - } - - public override Module GetModule(string name) - { - foreach (ModuleBuilder module in modules) - { - if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) - { - return module; - } - } - foreach (Module module in addedModules) - { - if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) - { - return module; - } - } - return null; - } - - public Module __AddModule(RawModule module) - { - Module mod = module.ToModule(this); - addedModules.Add(mod); - return mod; - } - - public override ManifestResourceInfo GetManifestResourceInfo(string resourceName) - { - throw new NotSupportedException(); - } - - public override string[] GetManifestResourceNames() - { - throw new NotSupportedException(); - } - - public override Stream GetManifestResourceStream(string resourceName) - { - throw new NotSupportedException(); - } - - internal override IList GetCustomAttributesData(Type attributeType) - { - List list = new List(); - foreach (CustomAttributeBuilder cab in customAttributes) - { - if (attributeType == null || attributeType.IsAssignableFrom(cab.Constructor.DeclaringType)) - { - list.Add(cab.ToData(this)); - } - } - return list; - } - - internal bool IsWindowsRuntime - { - get { return (flags & (AssemblyNameFlags)0x200) != 0; } - } - } - - sealed class ManifestModule : NonPEModule - { - private readonly AssemblyBuilder assembly; - private readonly Guid guid = Guid.NewGuid(); - - internal ManifestModule(AssemblyBuilder assembly) - : base(assembly.universe) - { - this.assembly = assembly; - } - - public override int MDStreamVersion - { - get { return assembly.mdStreamVersion; } - } - - public override Assembly Assembly - { - get { return assembly; } - } - - internal override Type FindType(TypeName typeName) - { - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - return null; - } - - internal override void GetTypesImpl(List list) - { - } - - public override string FullyQualifiedName - { - get { return Path.Combine(assembly.dir, "RefEmit_InMemoryManifestModule"); } - } - - public override string Name - { - get { return ""; } - } - - public override Guid ModuleVersionId - { - get { return guid; } - } - - public override string ScopeName - { - get { return "RefEmit_InMemoryManifestModule"; } - } - - protected override Exception NotSupportedException() - { - return new InvalidOperationException(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs b/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs deleted file mode 100644 index 308679dbb85..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/ConstructorBuilder.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection.Emit -{ - public sealed class ConstructorBuilder : ConstructorInfo - { - private readonly MethodBuilder methodBuilder; - - internal ConstructorBuilder(MethodBuilder mb) - { - this.methodBuilder = mb; - } - - public override bool Equals(object obj) - { - ConstructorBuilder other = obj as ConstructorBuilder; - return other != null && other.methodBuilder.Equals(methodBuilder); - } - - public override int GetHashCode() - { - return methodBuilder.GetHashCode(); - } - - public void __SetSignature(Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - methodBuilder.__SetSignature(returnType, returnTypeCustomModifiers, parameterTypes, parameterTypeCustomModifiers); - } - - [Obsolete("Please use __SetSignature(Type, CustomModifiers, Type[], CustomModifiers[]) instead.")] - public void __SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - methodBuilder.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); - } - - public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string strParamName) - { - return methodBuilder.DefineParameter(position, attributes, strParamName); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - methodBuilder.SetCustomAttribute(customBuilder); - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - methodBuilder.SetCustomAttribute(con, binaryAttribute); - } - - public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) - { - methodBuilder.__AddDeclarativeSecurity(customBuilder); - } - - public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet) - { - methodBuilder.AddDeclarativeSecurity(securityAction, permissionSet); - } - - public void SetImplementationFlags(MethodImplAttributes attributes) - { - methodBuilder.SetImplementationFlags(attributes); - } - - public ILGenerator GetILGenerator() - { - return methodBuilder.GetILGenerator(); - } - - public ILGenerator GetILGenerator(int streamSize) - { - return methodBuilder.GetILGenerator(streamSize); - } - - public void __ReleaseILGenerator() - { - methodBuilder.__ReleaseILGenerator(); - } - - public Type ReturnType - { - get { return methodBuilder.ReturnType; } - } - - public Module GetModule() - { - return methodBuilder.GetModule(); - } - - public MethodToken GetToken() - { - return methodBuilder.GetToken(); - } - - public bool InitLocals - { - get { return methodBuilder.InitLocals; } - set { methodBuilder.InitLocals = value; } - } - - internal override MethodInfo GetMethodInfo() - { - return methodBuilder; - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return methodBuilder; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs b/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs deleted file mode 100644 index 12be4a466d4..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/CustomAttributeBuilder.cs +++ /dev/null @@ -1,663 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class CustomAttributeBuilder - { - private readonly ConstructorInfo con; - private readonly byte[] blob; - private readonly object[] constructorArgs; - private readonly PropertyInfo[] namedProperties; - private readonly object[] propertyValues; - private readonly FieldInfo[] namedFields; - private readonly object[] fieldValues; - - internal CustomAttributeBuilder(ConstructorInfo con, byte[] blob) - { - this.con = con; - this.blob = blob; - } - - private CustomAttributeBuilder(ConstructorInfo con, int securityAction, byte[] blob) - { - this.con = con; - this.blob = blob; - this.constructorArgs = new object[] { securityAction }; - } - - public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs) - : this(con, constructorArgs, null, null, null,null) - { - } - - public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues) - : this(con, constructorArgs, null, null, namedFields, fieldValues) - { - } - - public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues) - : this(con, constructorArgs, namedProperties, propertyValues, null, null) - { - } - - public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues) - { - this.con = con; - this.constructorArgs = constructorArgs; - this.namedProperties = namedProperties; - this.propertyValues = propertyValues; - this.namedFields = namedFields; - this.fieldValues = fieldValues; - } - - public static CustomAttributeBuilder __FromBlob(ConstructorInfo con, byte[] blob) - { - return new CustomAttributeBuilder(con, blob); - } - - public static CustomAttributeBuilder __FromBlob(ConstructorInfo con, int securityAction, byte[] blob) - { - return new CustomAttributeBuilder(con, securityAction, blob); - } - - public static CustomAttributeTypedArgument __MakeTypedArgument(Type type, object value) - { - return new CustomAttributeTypedArgument(type, value); - } - - private sealed class BlobWriter - { - private readonly Assembly assembly; - private readonly CustomAttributeBuilder cab; - private readonly ByteBuffer bb; - - internal BlobWriter(Assembly assembly, CustomAttributeBuilder cab, ByteBuffer bb) - { - this.assembly = assembly; - this.cab = cab; - this.bb = bb; - } - - internal void WriteCustomAttributeBlob() - { - // prolog - WriteUInt16(1); - ParameterInfo[] pi = cab.con.GetParameters(); - for (int i = 0; i < pi.Length; i++) - { - WriteFixedArg(pi[i].ParameterType, cab.constructorArgs[i]); - } - WriteNamedArguments(false); - } - - internal void WriteNamedArguments(bool forDeclSecurity) - { - // NumNamed - int named = 0; - if (cab.namedFields != null) - { - named += cab.namedFields.Length; - } - if (cab.namedProperties != null) - { - named += cab.namedProperties.Length; - } - if (forDeclSecurity) - { - WritePackedLen(named); - } - else - { - WriteUInt16((ushort)named); - } - if (cab.namedFields != null) - { - for (int i = 0; i < cab.namedFields.Length; i++) - { - WriteNamedArg(0x53, cab.namedFields[i].FieldType, cab.namedFields[i].Name, cab.fieldValues[i]); - } - } - if (cab.namedProperties != null) - { - for (int i = 0; i < cab.namedProperties.Length; i++) - { - WriteNamedArg(0x54, cab.namedProperties[i].PropertyType, cab.namedProperties[i].Name, cab.propertyValues[i]); - } - } - } - - private void WriteNamedArg(byte fieldOrProperty, Type type, string name, object value) - { - WriteByte(fieldOrProperty); - WriteFieldOrPropType(type); - WriteString(name); - WriteFixedArg(type, value); - } - - private void WriteByte(byte value) - { - bb.Write(value); - } - - private void WriteUInt16(ushort value) - { - bb.Write(value); - } - - private void WriteInt32(int value) - { - bb.Write(value); - } - - private void WriteFixedArg(Type type, object value) - { - Universe u = assembly.universe; - if (type == u.System_String) - { - WriteString((string)value); - } - else if (type == u.System_Boolean) - { - WriteByte((bool)value ? (byte)1 : (byte)0); - } - else if (type == u.System_Char) - { - WriteUInt16((char)value); - } - else if (type == u.System_SByte) - { - WriteByte((byte)(sbyte)value); - } - else if (type == u.System_Byte) - { - WriteByte((byte)value); - } - else if (type == u.System_Int16) - { - WriteUInt16((ushort)(short)value); - } - else if (type == u.System_UInt16) - { - WriteUInt16((ushort)value); - } - else if (type == u.System_Int32) - { - WriteInt32((int)value); - } - else if (type == u.System_UInt32) - { - WriteInt32((int)(uint)value); - } - else if (type == u.System_Int64) - { - WriteInt64((long)value); - } - else if (type == u.System_UInt64) - { - WriteInt64((long)(ulong)value); - } - else if (type == u.System_Single) - { - WriteSingle((float)value); - } - else if (type == u.System_Double) - { - WriteDouble((double)value); - } - else if (type == u.System_Type) - { - WriteTypeName((Type)value); - } - else if (type == u.System_Object) - { - if (value == null) - { - type = u.System_String; - } - else if (value is Type) - { - // value.GetType() would return a subclass of Type, but we don't want to deal with that - type = u.System_Type; - } - else if (value is CustomAttributeTypedArgument) - { - CustomAttributeTypedArgument cta = (CustomAttributeTypedArgument)value; - value = cta.Value; - type = cta.ArgumentType; - } - else - { - type = u.Import(value.GetType()); - } - WriteFieldOrPropType(type); - WriteFixedArg(type, value); - } - else if (type.IsArray) - { - if (value == null) - { - WriteInt32(-1); - } - else - { - Array array = (Array)value; - Type elemType = type.GetElementType(); - WriteInt32(array.Length); - foreach (object val in array) - { - WriteFixedArg(elemType, val); - } - } - } - else if (type.IsEnum) - { - WriteFixedArg(type.GetEnumUnderlyingTypeImpl(), value); - } - else - { - throw new ArgumentException(); - } - } - - private void WriteInt64(long value) - { - bb.Write(value); - } - - private void WriteSingle(float value) - { - bb.Write(value); - } - - private void WriteDouble(double value) - { - bb.Write(value); - } - - private void WriteTypeName(Type type) - { - string name = null; - if (type != null) - { - StringBuilder sb = new StringBuilder(); - GetTypeName(sb, type, false); - name = sb.ToString(); - } - WriteString(name); - } - - private void GetTypeName(StringBuilder sb, Type type, bool isTypeParam) - { - bool v1 = !assembly.ManifestModule.__IsMissing && assembly.ManifestModule.MDStreamVersion < 0x20000; - bool includeAssemblyName = type.Assembly != assembly && (!v1 || type.Assembly != type.Module.universe.Mscorlib); - if (isTypeParam && includeAssemblyName) - { - sb.Append('['); - } - GetTypeNameImpl(sb, type); - if (includeAssemblyName) - { - if (v1) - { - sb.Append(','); - } - else - { - sb.Append(", "); - } - if (isTypeParam) - { - sb.Append(type.Assembly.FullName.Replace("]", "\\]")).Append(']'); - } - else - { - sb.Append(type.Assembly.FullName); - } - } - } - - private void GetTypeNameImpl(StringBuilder sb, Type type) - { - if (type.HasElementType) - { - GetTypeNameImpl(sb, type.GetElementType()); - sb.Append(((ElementHolderType)type).GetSuffix()); - } - else if (type.IsConstructedGenericType) - { - sb.Append(type.GetGenericTypeDefinition().FullName); - sb.Append('['); - string sep = ""; - foreach (Type typeParam in type.GetGenericArguments()) - { - sb.Append(sep); - GetTypeName(sb, typeParam, true); - sep = ","; - } - sb.Append(']'); - } - else - { - sb.Append(type.FullName); - } - } - - private void WriteString(string val) - { - bb.Write(val); - } - - private void WritePackedLen(int len) - { - bb.WriteCompressedInt(len); - } - - private void WriteFieldOrPropType(Type type) - { - Universe u = type.Module.universe; - if (type == u.System_Type) - { - WriteByte(0x50); - } - else if (type == u.System_Object) - { - WriteByte(0x51); - } - else if (type == u.System_Boolean) - { - WriteByte(0x02); - } - else if (type == u.System_Char) - { - WriteByte(0x03); - } - else if (type == u.System_SByte) - { - WriteByte(0x04); - } - else if (type == u.System_Byte) - { - WriteByte(0x05); - } - else if (type == u.System_Int16) - { - WriteByte(0x06); - } - else if (type == u.System_UInt16) - { - WriteByte(0x07); - } - else if (type == u.System_Int32) - { - WriteByte(0x08); - } - else if (type == u.System_UInt32) - { - WriteByte(0x09); - } - else if (type == u.System_Int64) - { - WriteByte(0x0A); - } - else if (type == u.System_UInt64) - { - WriteByte(0x0B); - } - else if (type == u.System_Single) - { - WriteByte(0x0C); - } - else if (type == u.System_Double) - { - WriteByte(0x0D); - } - else if (type == u.System_String) - { - WriteByte(0x0E); - } - else if (type.IsArray) - { - WriteByte(0x1D); - WriteFieldOrPropType(type.GetElementType()); - } - else if (type.IsEnum) - { - WriteByte(0x55); - WriteTypeName(type); - } - else - { - throw new ArgumentException(); - } - } - } - - internal bool IsPseudoCustomAttribute - { - get { return con.DeclaringType.IsPseudoCustomAttribute; } - } - - internal ConstructorInfo Constructor - { - get { return con; } - } - - internal int WriteBlob(ModuleBuilder moduleBuilder) - { - ByteBuffer bb; - if (blob != null) - { - bb = ByteBuffer.Wrap(blob); - } - else - { - bb = new ByteBuffer(100); - BlobWriter bw = new BlobWriter(moduleBuilder.Assembly, this, bb); - bw.WriteCustomAttributeBlob(); - } - return moduleBuilder.Blobs.Add(bb); - } - - internal object GetConstructorArgument(int pos) - { - return constructorArgs[pos]; - } - - internal int ConstructorArgumentCount - { - get { return constructorArgs == null ? 0 : constructorArgs.Length; } - } - - internal T? GetFieldValue(string name) where T : struct - { - object val = GetFieldValue(name); - if (val is T) - { - return (T)val; - } - else if (val != null) - { - if (typeof(T).IsEnum) - { - Debug.Assert(Enum.GetUnderlyingType(typeof(T)) == val.GetType()); - return (T)Enum.ToObject(typeof(T), val); - } - else - { - Debug.Assert(Enum.GetUnderlyingType(val.GetType()) == typeof(T)); - return (T)Convert.ChangeType(val, typeof(T)); - } - } - else - { - return null; - } - } - - internal object GetFieldValue(string name) - { - if (namedFields != null) - { - for (int i = 0; i < namedFields.Length; i++) - { - if (namedFields[i].Name == name) - { - return fieldValues[i]; - } - } - } - return null; - } - - internal string GetLegacyDeclSecurity() - { - if (con.DeclaringType == con.Module.universe.System_Security_Permissions_PermissionSetAttribute - && blob == null - && (namedFields == null || namedFields.Length == 0) - && namedProperties != null - && namedProperties.Length == 1 - && namedProperties[0].Name == "XML") - { - return propertyValues[0] as string; - } - return null; - } - - internal void WriteNamedArgumentsForDeclSecurity(ModuleBuilder moduleBuilder, ByteBuffer bb) - { - if (blob != null) - { - bb.Write(blob); - } - else - { - BlobWriter bw = new BlobWriter(moduleBuilder.Assembly, this, bb); - bw.WriteNamedArguments(true); - } - } - - internal CustomAttributeData ToData(Assembly asm) - { - if (blob != null) - { - if (constructorArgs != null) - { - return new CustomAttributeData(asm, con, (int)constructorArgs[0], blob, -1); - } - return new CustomAttributeData(asm, con, new IKVM.Reflection.Reader.ByteReader(blob, 0, blob.Length)); - } - else - { - List namedArgs = new List(); - if (namedProperties != null) - { - for (int i = 0; i < namedProperties.Length; i++) - { - namedArgs.Add(new CustomAttributeNamedArgument(namedProperties[i], RewrapValue(namedProperties[i].PropertyType, propertyValues[i]))); - } - } - if (namedFields != null) - { - for (int i = 0; i < namedFields.Length; i++) - { - namedArgs.Add(new CustomAttributeNamedArgument(namedFields[i], RewrapValue(namedFields[i].FieldType, fieldValues[i]))); - } - } - List args = new List(constructorArgs.Length); - ParameterInfo[] parameters = this.Constructor.GetParameters(); - for (int i = 0; i < constructorArgs.Length; i++) - { - args.Add(RewrapValue(parameters[i].ParameterType, constructorArgs[i])); - } - return new CustomAttributeData(asm.ManifestModule, con, args, namedArgs); - } - } - - private static CustomAttributeTypedArgument RewrapValue(Type type, object value) - { - if (value is Array) - { - Array array = (Array)value; - Type arrayType = type.Module.universe.Import(array.GetType()); - return RewrapArray(arrayType, array); - } - else if (value is CustomAttributeTypedArgument) - { - CustomAttributeTypedArgument arg = (CustomAttributeTypedArgument)value; - if (arg.Value is Array) - { - return RewrapArray(arg.ArgumentType, (Array)arg.Value); - } - return arg; - } - else - { - return new CustomAttributeTypedArgument(type, value); - } - } - - private static CustomAttributeTypedArgument RewrapArray(Type arrayType, Array array) - { - Type elementType = arrayType.GetElementType(); - CustomAttributeTypedArgument[] newArray = new CustomAttributeTypedArgument[array.Length]; - for (int i = 0; i < newArray.Length; i++) - { - newArray[i] = RewrapValue(elementType, array.GetValue(i)); - } - return new CustomAttributeTypedArgument(arrayType, newArray); - } - - internal bool HasBlob - { - get { return blob != null; } - } - - internal CustomAttributeBuilder DecodeBlob(Assembly asm) - { - if (blob == null) - { - return this; - } - else - { - return ToData(asm).__ToBuilder(); - } - } - - internal byte[] GetBlob(Assembly asm) - { - ByteBuffer bb = new ByteBuffer(100); - BlobWriter bw = new BlobWriter(asm, this, bb); - bw.WriteCustomAttributeBlob(); - return bb.ToArray(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/CustomModifiersBuilder.cs b/mcs/class/IKVM.Reflection/Emit/CustomModifiersBuilder.cs deleted file mode 100644 index 91f5b834aa7..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/CustomModifiersBuilder.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (C) 2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection.Emit -{ - public sealed class CustomModifiersBuilder - { - private readonly List list = new List(); - - internal struct Item - { - internal Type type; - internal bool required; - } - - public void AddRequired(Type type) - { - Item item; - item.type = type; - item.required = true; - list.Add(item); - } - - public void AddOptional(Type type) - { - Item item; - item.type = type; - item.required = false; - list.Add(item); - } - - // this adds the custom modifiers in the same order as the normal SRE APIs - // (the advantage over using the SRE APIs is that a CustomModifiers object is slightly more efficient, - // because unlike the Type arrays it doesn't need to be copied) - public void Add(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - foreach (CustomModifiers.Entry entry in CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)) - { - Item item; - item.type = entry.Type; - item.required = entry.IsRequired; - list.Add(item); - } - } - - public CustomModifiers Create() - { - return new CustomModifiers(list); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs b/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs deleted file mode 100644 index e93e7e736dd..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/EnumBuilder.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2010 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection.Emit -{ - public sealed class EnumBuilder : TypeInfo - { - private readonly TypeBuilder typeBuilder; - private readonly FieldBuilder fieldBuilder; - - internal EnumBuilder(TypeBuilder typeBuilder, FieldBuilder fieldBuilder) - : base(typeBuilder) - { - this.typeBuilder = typeBuilder; - this.fieldBuilder = fieldBuilder; - } - - public override string __Name - { - get { return typeBuilder.__Name; } - } - - public override string __Namespace - { - get { return typeBuilder.__Namespace; } - } - - public override string Name - { - get { return typeBuilder.Name; } - } - - public override string FullName - { - get { return typeBuilder.FullName; } - } - - public override Type BaseType - { - get { return typeBuilder.BaseType; } - } - - public override TypeAttributes Attributes - { - get { return typeBuilder.Attributes; } - } - - public override Module Module - { - get { return typeBuilder.Module; } - } - - public FieldBuilder DefineLiteral(string literalName, object literalValue) - { - FieldBuilder fb = typeBuilder.DefineField(literalName, typeBuilder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); - fb.SetConstant(literalValue); - return fb; - } - - public Type CreateType() - { - return typeBuilder.CreateType(); - } - - public TypeToken TypeToken - { - get { return typeBuilder.TypeToken; } - } - - public FieldBuilder UnderlyingField - { - get { return fieldBuilder; } - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - typeBuilder.SetCustomAttribute(con, binaryAttribute); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - typeBuilder.SetCustomAttribute(customBuilder); - } - - public override Type GetEnumUnderlyingType() - { - return fieldBuilder.FieldType; - } - - internal override bool IsBaked - { - get { return typeBuilder.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/Enums.cs b/mcs/class/IKVM.Reflection/Emit/Enums.cs deleted file mode 100644 index 7c85a55f67f..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/Enums.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ - -namespace IKVM.Reflection.Emit -{ - public enum AssemblyBuilderAccess - { - Save = 2, - ReflectionOnly = 6, - } - - public enum OpCodeType - { - Annotation = 0, - Macro = 1, - Nternal = 2, - Objmodel = 3, - Prefix = 4, - Primitive = 5, - } - - public enum OperandType - { - InlineBrTarget = 0, - InlineField = 1, - InlineI = 2, - InlineI8 = 3, - InlineMethod = 4, - InlineNone = 5, - InlinePhi = 6, - InlineR = 7, - InlineSig = 9, - InlineString = 10, - InlineSwitch = 11, - InlineTok = 12, - InlineType = 13, - InlineVar = 14, - ShortInlineBrTarget = 15, - ShortInlineI = 16, - ShortInlineR = 17, - ShortInlineVar = 18, - } - - public enum FlowControl - { - Branch = 0, - Break = 1, - Call = 2, - Cond_Branch = 3, - Meta = 4, - Next = 5, - Return = 7, - Throw = 8, - } - - public enum PackingSize - { - Unspecified = 0, - Size1 = 1, - Size2 = 2, - Size4 = 4, - Size8 = 8, - Size16 = 16, - Size32 = 32, - Size64 = 64, - Size128 = 128, - } - - public enum PEFileKinds - { - Dll = 1, - ConsoleApplication = 2, - WindowApplication = 3, - } - - public enum StackBehaviour - { - Pop0 = 0, - Pop1 = 1, - Pop1_pop1 = 2, - Popi = 3, - Popi_pop1 = 4, - Popi_popi = 5, - Popi_popi8 = 6, - Popi_popi_popi = 7, - Popi_popr4 = 8, - Popi_popr8 = 9, - Popref = 10, - Popref_pop1 = 11, - Popref_popi = 12, - Popref_popi_popi = 13, - Popref_popi_popi8 = 14, - Popref_popi_popr4 = 15, - Popref_popi_popr8 = 16, - Popref_popi_popref = 17, - Push0 = 18, - Push1 = 19, - Push1_push1 = 20, - Pushi = 21, - Pushi8 = 22, - Pushr4 = 23, - Pushr8 = 24, - Pushref = 25, - Varpop = 26, - Varpush = 27, - Popref_popi_pop1 = 28, - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs b/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs deleted file mode 100644 index 6e98d3711ea..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/EventBuilder.cs +++ /dev/null @@ -1,281 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class EventBuilder : EventInfo - { - private readonly TypeBuilder typeBuilder; - private readonly string name; - private EventAttributes attributes; - private readonly int eventtype; - private MethodBuilder addOnMethod; - private MethodBuilder removeOnMethod; - private MethodBuilder fireMethod; - private readonly List accessors = new List(); - private int lazyPseudoToken; - - private struct Accessor - { - internal short Semantics; - internal MethodBuilder Method; - } - - internal EventBuilder(TypeBuilder typeBuilder, string name, EventAttributes attributes, Type eventtype) - { - this.typeBuilder = typeBuilder; - this.name = name; - this.attributes = attributes; - this.eventtype = typeBuilder.ModuleBuilder.GetTypeTokenForMemberRef(eventtype); - } - - public void SetAddOnMethod(MethodBuilder mdBuilder) - { - addOnMethod = mdBuilder; - Accessor acc; - acc.Semantics = MethodSemanticsTable.AddOn; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void SetRemoveOnMethod(MethodBuilder mdBuilder) - { - removeOnMethod = mdBuilder; - Accessor acc; - acc.Semantics = MethodSemanticsTable.RemoveOn; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void SetRaiseMethod(MethodBuilder mdBuilder) - { - fireMethod = mdBuilder; - Accessor acc; - acc.Semantics = MethodSemanticsTable.Fire; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void AddOtherMethod(MethodBuilder mdBuilder) - { - Accessor acc; - acc.Semantics = MethodSemanticsTable.Other; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - Universe u = typeBuilder.ModuleBuilder.universe; - if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute) - { - attributes |= EventAttributes.SpecialName; - } - else - { - if (lazyPseudoToken == 0) - { - lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); - } - typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder); - } - } - - public override EventAttributes Attributes - { - get { return attributes; } - } - - public override MethodInfo GetAddMethod(bool nonPublic) - { - return nonPublic || (addOnMethod != null && addOnMethod.IsPublic) ? addOnMethod : null; - } - - public override MethodInfo GetRemoveMethod(bool nonPublic) - { - return nonPublic || (removeOnMethod != null && removeOnMethod.IsPublic) ? removeOnMethod : null; - } - - public override MethodInfo GetRaiseMethod(bool nonPublic) - { - return nonPublic || (fireMethod != null && fireMethod.IsPublic) ? fireMethod : null; - } - - public override MethodInfo[] GetOtherMethods(bool nonPublic) - { - List list = new List(); - foreach (Accessor acc in accessors) - { - if (acc.Semantics == MethodSemanticsTable.Other && (nonPublic || acc.Method.IsPublic)) - { - list.Add(acc.Method); - } - } - return list.ToArray(); - } - - public override MethodInfo[] __GetMethods() - { - List list = new List(); - foreach (Accessor acc in accessors) - { - list.Add(acc.Method); - } - return list.ToArray(); - } - - public override Type DeclaringType - { - get { return typeBuilder; } - } - - public override string Name - { - get { return name; } - } - - public override Module Module - { - get { return typeBuilder.ModuleBuilder; } - } - - public EventToken GetEventToken() - { - if (lazyPseudoToken == 0) - { - lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); - } - return new EventToken(lazyPseudoToken); - } - - public override Type EventHandlerType - { - get { return typeBuilder.ModuleBuilder.ResolveType(eventtype); } - } - - internal void Bake() - { - EventTable.Record rec = new EventTable.Record(); - rec.EventFlags = (short)attributes; - rec.Name = typeBuilder.ModuleBuilder.Strings.Add(name); - rec.EventType = eventtype; - int token = 0x14000000 | typeBuilder.ModuleBuilder.Event.AddRecord(rec); - - if (lazyPseudoToken == 0) - { - lazyPseudoToken = token; - } - else - { - typeBuilder.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, token); - } - - foreach (Accessor acc in accessors) - { - AddMethodSemantics(acc.Semantics, acc.Method.MetadataToken, token); - } - } - - private void AddMethodSemantics(short semantics, int methodToken, int propertyToken) - { - MethodSemanticsTable.Record rec = new MethodSemanticsTable.Record(); - rec.Semantics = semantics; - rec.Method = methodToken; - rec.Association = propertyToken; - typeBuilder.ModuleBuilder.MethodSemantics.AddRecord(rec); - } - - internal override bool IsPublic - { - get - { - foreach (Accessor acc in accessors) - { - if (acc.Method.IsPublic) - { - return true; - } - } - return false; - } - } - - internal override bool IsNonPrivate - { - get - { - foreach (Accessor acc in accessors) - { - if ((acc.Method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private) - { - return true; - } - } - return false; - } - } - - internal override bool IsStatic - { - get - { - foreach (Accessor acc in accessors) - { - if (acc.Method.IsStatic) - { - return true; - } - } - return false; - } - } - - internal override bool IsBaked - { - get { return typeBuilder.IsBaked; } - } - - internal override int GetCurrentToken() - { - if (typeBuilder.ModuleBuilder.IsSaved && typeBuilder.ModuleBuilder.IsPseudoToken(lazyPseudoToken)) - { - return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken); - } - else - { - return lazyPseudoToken; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/FieldBuilder.cs b/mcs/class/IKVM.Reflection/Emit/FieldBuilder.cs deleted file mode 100644 index cbee210b390..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/FieldBuilder.cs +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class FieldBuilder : FieldInfo - { - private readonly TypeBuilder typeBuilder; - private readonly string name; - private readonly int pseudoToken; - private FieldAttributes attribs; - private readonly int nameIndex; - private readonly int signature; - private readonly FieldSignature fieldSig; - - internal FieldBuilder(TypeBuilder type, string name, Type fieldType, CustomModifiers customModifiers, FieldAttributes attribs) - { - this.typeBuilder = type; - this.name = name; - this.pseudoToken = type.ModuleBuilder.AllocPseudoToken(); - this.nameIndex = type.ModuleBuilder.Strings.Add(name); - this.fieldSig = FieldSignature.Create(fieldType, customModifiers); - ByteBuffer sig = new ByteBuffer(5); - fieldSig.WriteSig(this.typeBuilder.ModuleBuilder, sig); - this.signature = this.typeBuilder.ModuleBuilder.Blobs.Add(sig); - this.attribs = attribs; - this.typeBuilder.ModuleBuilder.Field.AddVirtualRecord(); - } - - public void SetConstant(object defaultValue) - { - attribs |= FieldAttributes.HasDefault; - typeBuilder.ModuleBuilder.AddConstant(pseudoToken, defaultValue); - } - - public override object GetRawConstantValue() - { - if (!typeBuilder.IsCreated()) - { - // the .NET FieldBuilder doesn't support this method - // (since we dont' have a different FieldInfo object after baking, we will support it once we're baked) - throw new NotSupportedException(); - } - return typeBuilder.Module.Constant.GetRawConstantValue(typeBuilder.Module, GetCurrentToken()); - } - - public void __SetDataAndRVA(byte[] data) - { - SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.initializedData, 0); - } - - public void __SetReadOnlyDataAndRVA(byte[] data) - { - SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.methodBodies, unchecked((int)0x80000000)); - } - - private void SetDataAndRvaImpl(byte[] data, ByteBuffer bb, int readonlyMarker) - { - attribs |= FieldAttributes.HasFieldRVA; - FieldRVATable.Record rec = new FieldRVATable.Record(); - bb.Align(8); - rec.RVA = bb.Position + readonlyMarker; - rec.Field = pseudoToken; - typeBuilder.ModuleBuilder.FieldRVA.AddRecord(rec); - bb.Write(data); - } - - public override void __GetDataFromRVA(byte[] data, int offset, int length) - { - throw new NotImplementedException(); - } - - public override int __FieldRVA - { - get { throw new NotImplementedException(); } - } - - public override bool __TryGetFieldOffset(out int offset) - { - int pseudoTokenOrIndex = pseudoToken; - if (typeBuilder.ModuleBuilder.IsSaved) - { - pseudoTokenOrIndex = typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken) & 0xFFFFFF; - } - foreach (int i in this.Module.FieldLayout.Filter(pseudoTokenOrIndex)) - { - offset = this.Module.FieldLayout.records[i].Offset; - return true; - } - offset = 0; - return false; - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - Universe u = this.Module.universe; - if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_FieldOffsetAttribute) - { - customBuilder = customBuilder.DecodeBlob(this.Module.Assembly); - SetOffset((int)customBuilder.GetConstructorArgument(0)); - } - else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute) - { - FieldMarshal.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder); - attribs |= FieldAttributes.HasFieldMarshal; - } - else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute) - { - attribs |= FieldAttributes.NotSerialized; - } - else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute) - { - attribs |= FieldAttributes.SpecialName; - } - else - { - typeBuilder.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder); - } - } - - public void SetOffset(int iOffset) - { - FieldLayoutTable.Record rec = new FieldLayoutTable.Record(); - rec.Offset = iOffset; - rec.Field = pseudoToken; - typeBuilder.ModuleBuilder.FieldLayout.AddRecord(rec); - } - - public override FieldAttributes Attributes - { - get { return attribs; } - } - - public override Type DeclaringType - { - get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; } - } - - public override string Name - { - get { return name; } - } - - public override int MetadataToken - { - get { return pseudoToken; } - } - - public override Module Module - { - get { return typeBuilder.Module; } - } - - public FieldToken GetToken() - { - return new FieldToken(pseudoToken); - } - - internal void WriteFieldRecords(MetadataWriter mw) - { - mw.Write((short)attribs); - mw.WriteStringIndex(nameIndex); - mw.WriteBlobIndex(signature); - } - - internal void FixupToken(int token) - { - typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token); - } - - internal override FieldSignature FieldSignature - { - get { return fieldSig; } - } - - internal override int ImportTo(ModuleBuilder other) - { - return other.ImportMethodOrField(typeBuilder, name, fieldSig); - } - - internal override int GetCurrentToken() - { - if (typeBuilder.ModuleBuilder.IsSaved) - { - return typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken); - } - else - { - return pseudoToken; - } - } - - internal override bool IsBaked - { - get { return typeBuilder.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs b/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs deleted file mode 100644 index 7fddd7bcdb6..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/ILGenerator.cs +++ /dev/null @@ -1,1178 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using System.Diagnostics.SymbolStore; -using System.Diagnostics; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public struct Label - { - // 1-based here, to make sure that an uninitialized Label isn't valid - private readonly int index1; - - internal Label(int index) - { - this.index1 = index + 1; - } - - internal int Index - { - get { return index1 - 1; } - } - - public bool Equals(Label other) - { - return other.index1 == index1; - } - - public override bool Equals(object obj) - { - return this == obj as Label?; - } - - public override int GetHashCode() - { - return index1; - } - - public static bool operator ==(Label arg1, Label arg2) - { - return arg1.index1 == arg2.index1; - } - - public static bool operator !=(Label arg1, Label arg2) - { - return !(arg1 == arg2); - } - } - - public sealed class LocalBuilder - { - private readonly Type localType; - private readonly int index; - private readonly bool pinned; - internal string name; - internal int startOffset; - internal int endOffset; - - internal LocalBuilder(Type localType, int index, bool pinned) - { - this.localType = localType; - this.index = index; - this.pinned = pinned; - } - - public void SetLocalSymInfo(string name) - { - this.name = name; - } - - public void SetLocalSymInfo(string name, int startOffset, int endOffset) - { - this.name = name; - this.startOffset = startOffset; - this.endOffset = endOffset; - } - - public Type LocalType - { - get { return localType; } - } - - public int LocalIndex - { - get { return index; } - } - - public bool IsPinned - { - get { return pinned; } - } - } - - public sealed class ILGenerator - { - private readonly ModuleBuilder moduleBuilder; - private readonly ByteBuffer code; - private readonly SignatureHelper locals; - private int localsCount; - private readonly List tokenFixups = new List(); - private readonly List labels = new List(); - private readonly List labelStackHeight = new List(); - private readonly List labelFixups = new List(); - private readonly List sequencePoints = new List(); - private readonly List exceptions = new List(); - private readonly Stack exceptionStack = new Stack(); - private ushort maxStack; - private bool fatHeader; - private int stackHeight; - private Scope scope; - private byte exceptionBlockAssistanceMode = EBAM_COMPAT; - private const byte EBAM_COMPAT = 0; - private const byte EBAM_DISABLE = 1; - private const byte EBAM_CLEVER = 2; - - private struct LabelFixup - { - internal int label; - internal int offset; - } - - private sealed class ExceptionBlock : IComparer - { - internal readonly int ordinal; - internal Label labelEnd; - internal int tryOffset; - internal int tryLength; - internal int handlerOffset; - internal int handlerLength; - internal Type exceptionType; // MarkerType.Finally = finally block, MarkerType.Filter = handler with filter, MarkerType.Fault = fault block - internal int filterOffset; - - internal ExceptionBlock(int ordinal) - { - this.ordinal = ordinal; - } - - int IComparer.Compare(ExceptionBlock x, ExceptionBlock y) - { - // Mono's sort insists on doing unnecessary comparisons - if (x == y) - { - return 0; - } - else if (x.tryOffset == y.tryOffset && x.tryLength == y.tryLength) - { - return x.ordinal < y.ordinal ? -1 : 1; - } - else if (x.tryOffset >= y.tryOffset && x.handlerOffset + x.handlerLength <= y.handlerOffset + y.handlerLength) - { - return -1; - } - else if (y.tryOffset >= x.tryOffset && y.handlerOffset + y.handlerLength <= x.handlerOffset + x.handlerLength) - { - return 1; - } - else - { - return x.ordinal < y.ordinal ? -1 : 1; - } - } - } - - private struct SequencePoint - { - internal ISymbolDocumentWriter document; - internal int offset; - internal int startLine; - internal int startColumn; - internal int endLine; - internal int endColumn; - } - - private sealed class Scope - { - internal readonly Scope parent; - internal readonly List children = new List(); - internal readonly List locals = new List(); - internal int startOffset; - internal int endOffset; - - internal Scope(Scope parent) - { - this.parent = parent; - } - } - - internal ILGenerator(ModuleBuilder moduleBuilder, int initialCapacity) - { - this.code = new ByteBuffer(initialCapacity); - this.moduleBuilder = moduleBuilder; - this.locals = SignatureHelper.GetLocalVarSigHelper(moduleBuilder); - if (moduleBuilder.symbolWriter != null) - { - scope = new Scope(null); - } - } - - // non-standard API - public void __DisableExceptionBlockAssistance() - { - exceptionBlockAssistanceMode = EBAM_DISABLE; - } - - // non-standard API - public void __CleverExceptionBlockAssistance() - { - exceptionBlockAssistanceMode = EBAM_CLEVER; - } - - // non-standard API - public int __MaxStackSize - { - get { return maxStack; } - set - { - maxStack = (ushort)value; - fatHeader = true; - } - } - - // non-standard API - // returns -1 if the current position is currently unreachable - public int __StackHeight - { - get { return stackHeight; } - } - - // new in .NET 4.0 - public int ILOffset - { - get { return code.Position; } - } - - public void BeginCatchBlock(Type exceptionType) - { - ExceptionBlock block = exceptionStack.Peek(); - if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) - { - if (exceptionType == null) - { - Emit(OpCodes.Endfilter); - } - else - { - Emit(OpCodes.Leave, block.labelEnd); - } - } - stackHeight = 0; - UpdateStack(1); - if (exceptionType == null) - { - if (block.exceptionType != MarkerType.Filter || block.handlerOffset != 0) - { - throw new ArgumentNullException("exceptionType"); - } - block.handlerOffset = code.Position; - } - else - { - if (block.tryLength == 0) - { - block.tryLength = code.Position - block.tryOffset; - } - else - { - block.handlerLength = code.Position - block.handlerOffset; - exceptionStack.Pop(); - ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); - newBlock.labelEnd = block.labelEnd; - newBlock.tryOffset = block.tryOffset; - newBlock.tryLength = block.tryLength; - block = newBlock; - exceptions.Add(block); - exceptionStack.Push(block); - } - block.exceptionType = exceptionType; - if (exceptionType == MarkerType.Filter) - { - block.filterOffset = code.Position; - } - else - { - block.handlerOffset = code.Position; - } - } - } - - public Label BeginExceptionBlock() - { - ExceptionBlock block = new ExceptionBlock(exceptions.Count); - block.labelEnd = DefineLabel(); - block.tryOffset = code.Position; - exceptionStack.Push(block); - exceptions.Add(block); - stackHeight = 0; - return block.labelEnd; - } - - public void BeginExceptFilterBlock() - { - BeginCatchBlock(MarkerType.Filter); - } - - public void BeginFaultBlock() - { - BeginFinallyFaultBlock(MarkerType.Fault); - } - - public void BeginFinallyBlock() - { - BeginFinallyFaultBlock(MarkerType.Finally); - } - - private void BeginFinallyFaultBlock(Type type) - { - ExceptionBlock block = exceptionStack.Peek(); - if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) - { - Emit(OpCodes.Leave, block.labelEnd); - } - if (block.handlerOffset == 0) - { - block.tryLength = code.Position - block.tryOffset; - } - else - { - block.handlerLength = code.Position - block.handlerOffset; - Label labelEnd; - if (exceptionBlockAssistanceMode != EBAM_COMPAT) - { - labelEnd = block.labelEnd; - } - else - { - MarkLabel(block.labelEnd); - labelEnd = DefineLabel(); - Emit(OpCodes.Leave, labelEnd); - } - exceptionStack.Pop(); - ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); - newBlock.labelEnd = labelEnd; - newBlock.tryOffset = block.tryOffset; - newBlock.tryLength = code.Position - block.tryOffset; - block = newBlock; - exceptions.Add(block); - exceptionStack.Push(block); - } - block.handlerOffset = code.Position; - block.exceptionType = type; - stackHeight = 0; - } - - public void EndExceptionBlock() - { - ExceptionBlock block = exceptionStack.Pop(); - if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) - { - if (block.filterOffset != 0 || (block.exceptionType != MarkerType.Finally && block.exceptionType != MarkerType.Fault)) - { - Emit(OpCodes.Leave, block.labelEnd); - } - else - { - Emit(OpCodes.Endfinally); - } - } - MarkLabel(block.labelEnd); - block.handlerLength = code.Position - block.handlerOffset; - } - - public void BeginScope() - { - Scope newScope = new Scope(scope); - scope.children.Add(newScope); - scope = newScope; - scope.startOffset = code.Position; - } - - public void UsingNamespace(string usingNamespace) - { - if (moduleBuilder.symbolWriter != null) - { - moduleBuilder.symbolWriter.UsingNamespace(usingNamespace); - } - } - - public LocalBuilder DeclareLocal(Type localType) - { - return DeclareLocal(localType, false); - } - - public LocalBuilder DeclareLocal(Type localType, bool pinned) - { - LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned); - locals.AddArgument(localType, pinned); - if (scope != null) - { - scope.locals.Add(local); - } - return local; - } - - public LocalBuilder __DeclareLocal(Type localType, bool pinned, CustomModifiers customModifiers) - { - LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned); - locals.__AddArgument(localType, pinned, customModifiers); - if (scope != null) - { - scope.locals.Add(local); - } - return local; - } - - public Label DefineLabel() - { - Label label = new Label(labels.Count); - labels.Add(-1); - labelStackHeight.Add(-1); - return label; - } - - public void Emit(OpCode opc) - { - Debug.Assert(opc != OpCodes.Ret || (opc == OpCodes.Ret && stackHeight <= 1)); - if (opc.Value < 0) - { - code.Write((byte)(opc.Value >> 8)); - } - code.Write((byte)opc.Value); - switch (opc.FlowControl) - { - case FlowControl.Branch: - case FlowControl.Break: - case FlowControl.Return: - case FlowControl.Throw: - stackHeight = -1; - break; - default: - UpdateStack(opc.StackDiff); - break; - } - } - - private void UpdateStack(int stackdiff) - { - if (stackHeight == -1) - { - // we're about to emit code that is either unreachable or reachable only via a backward branch - stackHeight = 0; - } - Debug.Assert(stackHeight >= 0 && stackHeight <= ushort.MaxValue); - stackHeight += stackdiff; - Debug.Assert(stackHeight >= 0 && stackHeight <= ushort.MaxValue); - maxStack = Math.Max(maxStack, (ushort)stackHeight); - } - - public void Emit(OpCode opc, byte arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, double arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, FieldInfo field) - { - Emit(opc); - WriteToken(moduleBuilder.GetFieldToken(field)); - } - - public void Emit(OpCode opc, short arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, int arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, long arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, Label label) - { - // We need special stackHeight handling for unconditional branches, - // because the branch and next flows have differing stack heights. - // Note that this assumes that unconditional branches do not push/pop. - int flowStackHeight = this.stackHeight; - Emit(opc); - if (opc == OpCodes.Leave || opc == OpCodes.Leave_S) - { - flowStackHeight = 0; - } - else if (opc.FlowControl != FlowControl.Branch) - { - flowStackHeight = this.stackHeight; - } - // if the label has already been marked, we can emit the branch offset directly - if (labels[label.Index] != -1) - { - if (labelStackHeight[label.Index] != flowStackHeight && (labelStackHeight[label.Index] != 0 || flowStackHeight != -1)) - { - // the "backward branch constraint" prohibits this, so we don't need to support it - throw new NotSupportedException("'Backward branch constraints' violated"); - } - if (opc.OperandType == OperandType.ShortInlineBrTarget) - { - WriteByteBranchOffset(labels[label.Index] - (code.Position + 1)); - } - else - { - code.Write(labels[label.Index] - (code.Position + 4)); - } - } - else - { - Debug.Assert(labelStackHeight[label.Index] == -1 || labelStackHeight[label.Index] == flowStackHeight || (flowStackHeight == -1 && labelStackHeight[label.Index] == 0)); - labelStackHeight[label.Index] = flowStackHeight; - LabelFixup fix = new LabelFixup(); - fix.label = label.Index; - fix.offset = code.Position; - labelFixups.Add(fix); - if (opc.OperandType == OperandType.ShortInlineBrTarget) - { - code.Write((byte)1); - } - else - { - code.Write(4); - } - } - } - - private void WriteByteBranchOffset(int offset) - { - if (offset < -128 || offset > 127) - { - throw new NotSupportedException("Branch offset of " + offset + " does not fit in one-byte branch target at position " + code.Position); - } - code.Write((byte)offset); - } - - public void Emit(OpCode opc, Label[] labels) - { - Emit(opc); - LabelFixup fix = new LabelFixup(); - fix.label = -1; - fix.offset = code.Position; - labelFixups.Add(fix); - code.Write(labels.Length); - foreach (Label label in labels) - { - code.Write(label.Index); - if (this.labels[label.Index] != -1) - { - if (labelStackHeight[label.Index] != stackHeight) - { - // the "backward branch constraint" prohibits this, so we don't need to support it - throw new NotSupportedException(); - } - } - else - { - Debug.Assert(labelStackHeight[label.Index] == -1 || labelStackHeight[label.Index] == stackHeight); - labelStackHeight[label.Index] = stackHeight; - } - } - } - - public void Emit(OpCode opc, LocalBuilder local) - { - if ((opc == OpCodes.Ldloc || opc == OpCodes.Ldloca || opc == OpCodes.Stloc) && local.LocalIndex < 256) - { - if (opc == OpCodes.Ldloc) - { - switch (local.LocalIndex) - { - case 0: - Emit(OpCodes.Ldloc_0); - break; - case 1: - Emit(OpCodes.Ldloc_1); - break; - case 2: - Emit(OpCodes.Ldloc_2); - break; - case 3: - Emit(OpCodes.Ldloc_3); - break; - default: - Emit(OpCodes.Ldloc_S); - code.Write((byte)local.LocalIndex); - break; - } - } - else if (opc == OpCodes.Ldloca) - { - Emit(OpCodes.Ldloca_S); - code.Write((byte)local.LocalIndex); - } - else if (opc == OpCodes.Stloc) - { - switch (local.LocalIndex) - { - case 0: - Emit(OpCodes.Stloc_0); - break; - case 1: - Emit(OpCodes.Stloc_1); - break; - case 2: - Emit(OpCodes.Stloc_2); - break; - case 3: - Emit(OpCodes.Stloc_3); - break; - default: - Emit(OpCodes.Stloc_S); - code.Write((byte)local.LocalIndex); - break; - } - } - } - else - { - Emit(opc); - switch (opc.OperandType) - { - case OperandType.InlineVar: - code.Write((ushort)local.LocalIndex); - break; - case OperandType.ShortInlineVar: - code.Write((byte)local.LocalIndex); - break; - } - } - } - - private void WriteToken(FieldToken token) - { - if (token.IsPseudoToken) - { - tokenFixups.Add(code.Position); - } - code.Write(token.Token); - } - - private void WriteToken(MethodToken token) - { - if (token.IsPseudoToken) - { - tokenFixups.Add(code.Position); - } - code.Write(token.Token); - } - - private void UpdateStack(OpCode opc, bool hasthis, Type returnType, int parameterCount) - { - if (opc == OpCodes.Jmp) - { - stackHeight = -1; - } - else if (opc.FlowControl == FlowControl.Call) - { - int stackdiff = 0; - if ((hasthis && opc != OpCodes.Newobj) || opc == OpCodes.Calli) - { - // pop this - stackdiff--; - } - // pop parameters - stackdiff -= parameterCount; - if (returnType != moduleBuilder.universe.System_Void) - { - // push return value - stackdiff++; - } - UpdateStack(stackdiff); - } - } - - public void Emit(OpCode opc, MethodInfo method) - { - UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount); - Emit(opc); - WriteToken(moduleBuilder.GetMethodTokenForIL(method)); - } - - public void Emit(OpCode opc, ConstructorInfo constructor) - { - Emit(opc, constructor.GetMethodInfo()); - } - - public void Emit(OpCode opc, sbyte arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, float arg) - { - Emit(opc); - code.Write(arg); - } - - public void Emit(OpCode opc, string str) - { - Emit(opc); - code.Write(moduleBuilder.GetStringConstant(str).Token); - } - - public void Emit(OpCode opc, Type type) - { - Emit(opc); - if (opc == OpCodes.Ldtoken) - { - code.Write(moduleBuilder.GetTypeToken(type).Token); - } - else - { - code.Write(moduleBuilder.GetTypeTokenForMemberRef(type)); - } - } - - public void Emit(OpCode opcode, SignatureHelper signature) - { - Emit(opcode); - UpdateStack(opcode, signature.HasThis, signature.ReturnType, signature.ParameterCount); - code.Write(moduleBuilder.GetSignatureToken(signature).Token); - } - - public void EmitCall(OpCode opc, MethodInfo method, Type[] optionalParameterTypes) - { - __EmitCall(opc, method, optionalParameterTypes, null); - } - - public void __EmitCall(OpCode opc, MethodInfo method, Type[] optionalParameterTypes, CustomModifiers[] customModifiers) - { - if (optionalParameterTypes == null || optionalParameterTypes.Length == 0) - { - Emit(opc, method); - } - else - { - Emit(opc); - UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount + optionalParameterTypes.Length); - code.Write(moduleBuilder.__GetMethodToken(method, optionalParameterTypes, customModifiers).Token); - } - } - - public void __EmitCall(OpCode opc, ConstructorInfo constructor, Type[] optionalParameterTypes) - { - EmitCall(opc, constructor.GetMethodInfo(), optionalParameterTypes); - } - - public void __EmitCall(OpCode opc, ConstructorInfo constructor, Type[] optionalParameterTypes, CustomModifiers[] customModifiers) - { - __EmitCall(opc, constructor.GetMethodInfo(), optionalParameterTypes, customModifiers); - } - - public void EmitCalli(OpCode opc, CallingConvention callingConvention, Type returnType, Type[] parameterTypes) - { - SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType); - sig.AddArguments(parameterTypes, null, null); - Emit(opc, sig); - } - - public void EmitCalli(OpCode opc, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) - { - SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType); - sig.AddArguments(parameterTypes, null, null); - sig.AddSentinel(); - sig.AddArguments(optionalParameterTypes, null, null); - Emit(opc, sig); - } - - public void __EmitCalli(OpCode opc, __StandAloneMethodSig sig) - { - Emit(opc); - if (sig.IsUnmanaged) - { - UpdateStack(opc, false, sig.ReturnType, sig.ParameterCount); - } - else - { - CallingConventions callingConvention = sig.CallingConvention; - UpdateStack(opc, (callingConvention & CallingConventions.HasThis | CallingConventions.ExplicitThis) == CallingConventions.HasThis, sig.ReturnType, sig.ParameterCount); - } - ByteBuffer bb = new ByteBuffer(16); - Signature.WriteStandAloneMethodSig(moduleBuilder, bb, sig); - code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(bb))); - } - - public void EmitWriteLine(string text) - { - Universe u = moduleBuilder.universe; - Emit(OpCodes.Ldstr, text); - Emit(OpCodes.Call, u.Import(typeof(Console)).GetMethod("WriteLine", new Type[] { u.System_String })); - } - - public void EmitWriteLine(FieldInfo field) - { - Universe u = moduleBuilder.universe; - Emit(OpCodes.Call, u.Import(typeof(Console)).GetMethod("get_Out")); - if (field.IsStatic) - { - Emit(OpCodes.Ldsfld, field); - } - else - { - Emit(OpCodes.Ldarg_0); - Emit(OpCodes.Ldfld, field); - } - Emit(OpCodes.Callvirt, u.Import(typeof(System.IO.TextWriter)).GetMethod("WriteLine", new Type[] { field.FieldType })); - } - - public void EmitWriteLine(LocalBuilder local) - { - Universe u = moduleBuilder.universe; - Emit(OpCodes.Call, u.Import(typeof(Console)).GetMethod("get_Out")); - Emit(OpCodes.Ldloc, local); - Emit(OpCodes.Callvirt, u.Import(typeof(System.IO.TextWriter)).GetMethod("WriteLine", new Type[] { local.LocalType })); - } - - public void EndScope() - { - scope.endOffset = code.Position; - scope = scope.parent; - } - - public void MarkLabel(Label loc) - { - Debug.Assert(stackHeight == -1 || labelStackHeight[loc.Index] == -1 || stackHeight == labelStackHeight[loc.Index]); - labels[loc.Index] = code.Position; - if (labelStackHeight[loc.Index] == -1) - { - if (stackHeight == -1) - { - // We're at a location that can only be reached by a backward branch, - // so according to the "backward branch constraint" that must mean the stack is empty, - // but note that this may be an unused label followed by another label that is used and - // that does have a non-zero stack height, so we don't yet set stackHeight here. - labelStackHeight[loc.Index] = 0; - } - else - { - labelStackHeight[loc.Index] = stackHeight; - } - } - else - { - Debug.Assert(stackHeight == -1 || stackHeight == labelStackHeight[loc.Index]); - stackHeight = labelStackHeight[loc.Index]; - } - } - - public void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn) - { - SequencePoint sp = new SequencePoint(); - sp.document = document; - sp.offset = code.Position; - sp.startLine = startLine; - sp.startColumn = startColumn; - sp.endLine = endLine; - sp.endColumn = endColumn; - sequencePoints.Add(sp); - } - - public void ThrowException(Type excType) - { - Emit(OpCodes.Newobj, excType.GetConstructor(Type.EmptyTypes)); - Emit(OpCodes.Throw); - } - - internal int WriteBody(bool initLocals) - { - if (moduleBuilder.symbolWriter != null) - { - Debug.Assert(scope != null && scope.parent == null); - scope.endOffset = code.Position; - } - - ResolveBranches(); - - ByteBuffer bb = moduleBuilder.methodBodies; - - int localVarSigTok = 0; - - int rva; - if (localsCount == 0 && exceptions.Count == 0 && maxStack <= 8 && code.Length < 64 && !fatHeader) - { - rva = WriteTinyHeaderAndCode(bb); - } - else - { - rva = WriteFatHeaderAndCode(bb, ref localVarSigTok, initLocals); - } - - if (moduleBuilder.symbolWriter != null) - { - if (sequencePoints.Count != 0) - { - ISymbolDocumentWriter document = sequencePoints[0].document; - int[] offsets = new int[sequencePoints.Count]; - int[] lines = new int[sequencePoints.Count]; - int[] columns = new int[sequencePoints.Count]; - int[] endLines = new int[sequencePoints.Count]; - int[] endColumns = new int[sequencePoints.Count]; - for (int i = 0; i < sequencePoints.Count; i++) - { - if (sequencePoints[i].document != document) - { - throw new NotImplementedException(); - } - offsets[i] = sequencePoints[i].offset; - lines[i] = sequencePoints[i].startLine; - columns[i] = sequencePoints[i].startColumn; - endLines[i] = sequencePoints[i].endLine; - endColumns[i] = sequencePoints[i].endColumn; - } - moduleBuilder.symbolWriter.DefineSequencePoints(document, offsets, lines, columns, endLines, endColumns); - } - - WriteScope(scope, localVarSigTok); - } - return rva; - } - - private void ResolveBranches() - { - foreach (LabelFixup fixup in labelFixups) - { - // is it a switch? - if (fixup.label == -1) - { - code.Position = fixup.offset; - int count = code.GetInt32AtCurrentPosition(); - int offset = fixup.offset + 4 + 4 * count; - code.Position += 4; - for (int i = 0; i < count; i++) - { - int index = code.GetInt32AtCurrentPosition(); - code.Write(labels[index] - offset); - } - } - else - { - code.Position = fixup.offset; - byte size = code.GetByteAtCurrentPosition(); - int branchOffset = labels[fixup.label] - (code.Position + size); - if (size == 1) - { - WriteByteBranchOffset(branchOffset); - } - else - { - code.Write(branchOffset); - } - } - } - } - - private int WriteTinyHeaderAndCode(ByteBuffer bb) - { - int rva = bb.Position; - const byte CorILMethod_TinyFormat = 0x2; - bb.Write((byte)(CorILMethod_TinyFormat | (code.Length << 2))); - WriteCode(bb); - return rva; - } - - private int WriteFatHeaderAndCode(ByteBuffer bb, ref int localVarSigTok, bool initLocals) - { - // fat headers require 4-byte alignment - bb.Align(4); - int rva = bb.Position; - - if (localsCount != 0) - { - localVarSigTok = moduleBuilder.GetSignatureToken(locals).Token; - } - - const byte CorILMethod_FatFormat = 0x03; - const byte CorILMethod_MoreSects = 0x08; - const byte CorILMethod_InitLocals = 0x10; - - short flagsAndSize = (short)(CorILMethod_FatFormat | (3 << 12)); - if (initLocals) - { - flagsAndSize |= CorILMethod_InitLocals; - } - - if (exceptions.Count > 0) - { - flagsAndSize |= CorILMethod_MoreSects; - } - - bb.Write(flagsAndSize); - bb.Write(maxStack); - bb.Write(code.Length); - bb.Write(localVarSigTok); - - WriteCode(bb); - - if (exceptions.Count > 0) - { - bb.Align(4); - - bool fat = false; - foreach (ExceptionBlock block in exceptions) - { - if (block.tryOffset > 65535 || block.tryLength > 255 || block.handlerOffset > 65535 || block.handlerLength > 255) - { - fat = true; - break; - } - } - exceptions.Sort(exceptions[0]); - if (exceptions.Count * 12 + 4 > 255) - { - fat = true; - } - const byte CorILMethod_Sect_EHTable = 0x1; - const byte CorILMethod_Sect_FatFormat = 0x40; - const short COR_ILEXCEPTION_CLAUSE_EXCEPTION = 0x0000; - const short COR_ILEXCEPTION_CLAUSE_FILTER = 0x0001; - const short COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002; - const short COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004; - - if (fat) - { - bb.Write((byte)(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat)); - int dataSize = exceptions.Count * 24 + 4; - bb.Write((byte)dataSize); - bb.Write((short)(dataSize >> 8)); - foreach (ExceptionBlock block in exceptions) - { - if (block.exceptionType == MarkerType.Fault) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FAULT); - } - else if (block.exceptionType == MarkerType.Filter) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FILTER); - } - else if (block.exceptionType == MarkerType.Finally) - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY); - } - else - { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_EXCEPTION); - } - bb.Write(block.tryOffset); - bb.Write(block.tryLength); - bb.Write(block.handlerOffset); - bb.Write(block.handlerLength); - if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) - { - bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); - } - else - { - bb.Write(block.filterOffset); - } - } - } - else - { - bb.Write(CorILMethod_Sect_EHTable); - bb.Write((byte)(exceptions.Count * 12 + 4)); - bb.Write((short)0); - foreach (ExceptionBlock block in exceptions) - { - if (block.exceptionType == MarkerType.Fault) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FAULT); - } - else if (block.exceptionType == MarkerType.Filter) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FILTER); - } - else if (block.exceptionType == MarkerType.Finally) - { - bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY); - } - else - { - bb.Write(COR_ILEXCEPTION_CLAUSE_EXCEPTION); - } - bb.Write((short)block.tryOffset); - bb.Write((byte)block.tryLength); - bb.Write((short)block.handlerOffset); - bb.Write((byte)block.handlerLength); - if (block.exceptionType != MarkerType.Fault && block.exceptionType != MarkerType.Filter && block.exceptionType != MarkerType.Finally) - { - bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); - } - else - { - bb.Write(block.filterOffset); - } - } - } - } - return rva; - } - - private void WriteCode(ByteBuffer bb) - { - int codeOffset = bb.Position; - foreach (int fixup in this.tokenFixups) - { - moduleBuilder.tokenFixupOffsets.Add(fixup + codeOffset); - } - bb.Write(code); - } - - private void WriteScope(Scope scope, int localVarSigTok) - { - moduleBuilder.symbolWriter.OpenScope(scope.startOffset); - foreach (LocalBuilder local in scope.locals) - { - if (local.name != null) - { - int startOffset = local.startOffset; - int endOffset = local.endOffset; - if (startOffset == 0 && endOffset == 0) - { - startOffset = scope.startOffset; - endOffset = scope.endOffset; - } - moduleBuilder.symbolWriter.DefineLocalVariable2(local.name, 0, localVarSigTok, SymAddressKind.ILOffset, local.LocalIndex, 0, 0, startOffset, endOffset); - } - } - foreach (Scope child in scope.children) - { - WriteScope(child, localVarSigTok); - } - moduleBuilder.symbolWriter.CloseScope(scope.endOffset); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs b/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs deleted file mode 100644 index 89778acdb47..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/MethodBuilder.cs +++ /dev/null @@ -1,726 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using System.Diagnostics; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using System.Diagnostics.SymbolStore; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class MethodBuilder : MethodInfo - { - private readonly TypeBuilder typeBuilder; - private readonly string name; - private readonly int pseudoToken; - private int nameIndex; - private int signature; - private Type returnType; - private Type[] parameterTypes; - private PackedCustomModifiers customModifiers; - private MethodAttributes attributes; - private MethodImplAttributes implFlags; - private ILGenerator ilgen; - private int rva = -1; - private CallingConventions callingConvention; - private List parameters; - private GenericTypeParameterBuilder[] gtpb; - private List declarativeSecurity; - private MethodSignature methodSignature; - private bool initLocals = true; - - internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention) - { - this.typeBuilder = typeBuilder; - this.name = name; - this.pseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); - this.attributes = attributes; - if ((attributes & MethodAttributes.Static) == 0) - { - callingConvention |= CallingConventions.HasThis; - } - this.callingConvention = callingConvention; - } - - public ILGenerator GetILGenerator() - { - return GetILGenerator(16); - } - - public ILGenerator GetILGenerator(int streamSize) - { - if (rva != -1) - { - throw new InvalidOperationException(); - } - if (ilgen == null) - { - ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize); - } - return ilgen; - } - - public void __ReleaseILGenerator() - { - if (ilgen != null) - { - if (this.ModuleBuilder.symbolWriter != null) - { - this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000), this); - } - rva = ilgen.WriteBody(initLocals); - if (this.ModuleBuilder.symbolWriter != null) - { - this.ModuleBuilder.symbolWriter.CloseMethod(); - } - ilgen = null; - } - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - private void SetDllImportPseudoCustomAttribute(CustomAttributeBuilder customBuilder) - { - CallingConvention? callingConvention = customBuilder.GetFieldValue("CallingConvention"); - CharSet? charSet = customBuilder.GetFieldValue("CharSet"); - SetDllImportPseudoCustomAttribute((string)customBuilder.GetConstructorArgument(0), - (string)customBuilder.GetFieldValue("EntryPoint"), - callingConvention, - charSet, - (bool?)customBuilder.GetFieldValue("BestFitMapping"), - (bool?)customBuilder.GetFieldValue("ThrowOnUnmappableChar"), - (bool?)customBuilder.GetFieldValue("SetLastError"), - (bool?)customBuilder.GetFieldValue("PreserveSig"), - (bool?)customBuilder.GetFieldValue("ExactSpelling")); - } - - internal void SetDllImportPseudoCustomAttribute(string dllName, string entryName, CallingConvention? nativeCallConv, CharSet? nativeCharSet, - bool? bestFitMapping, bool? throwOnUnmappableChar, bool? setLastError, bool? preserveSig, bool? exactSpelling) - { - const short NoMangle = 0x0001; - const short CharSetMask = 0x0006; - const short CharSetNotSpec = 0x0000; - const short CharSetAnsi = 0x0002; - const short CharSetUnicode = 0x0004; - const short CharSetAuto = 0x0006; - const short SupportsLastError = 0x0040; - const short CallConvMask = 0x0700; - const short CallConvWinapi = 0x0100; - const short CallConvCdecl = 0x0200; - const short CallConvStdcall = 0x0300; - const short CallConvThiscall = 0x0400; - const short CallConvFastcall = 0x0500; - // non-standard flags - const short BestFitOn = 0x0010; - const short BestFitOff = 0x0020; - const short CharMapErrorOn = 0x1000; - const short CharMapErrorOff = 0x2000; - short flags = CharSetNotSpec | CallConvWinapi; - if (bestFitMapping.HasValue) - { - flags |= bestFitMapping.Value ? BestFitOn : BestFitOff; - } - if (throwOnUnmappableChar.HasValue) - { - flags |= throwOnUnmappableChar.Value ? CharMapErrorOn : CharMapErrorOff; - } - if (nativeCallConv.HasValue) - { - flags &= ~CallConvMask; - switch (nativeCallConv.Value) - { - case System.Runtime.InteropServices.CallingConvention.Cdecl: - flags |= CallConvCdecl; - break; - case System.Runtime.InteropServices.CallingConvention.FastCall: - flags |= CallConvFastcall; - break; - case System.Runtime.InteropServices.CallingConvention.StdCall: - flags |= CallConvStdcall; - break; - case System.Runtime.InteropServices.CallingConvention.ThisCall: - flags |= CallConvThiscall; - break; - case System.Runtime.InteropServices.CallingConvention.Winapi: - flags |= CallConvWinapi; - break; - } - } - if (nativeCharSet.HasValue) - { - flags &= ~CharSetMask; - switch (nativeCharSet.Value) - { - case CharSet.Ansi: - case CharSet.None: - flags |= CharSetAnsi; - break; - case CharSet.Auto: - flags |= CharSetAuto; - break; - case CharSet.Unicode: - flags |= CharSetUnicode; - break; - } - } - if (exactSpelling.HasValue && exactSpelling.Value) - { - flags |= NoMangle; - } - if (!preserveSig.HasValue || preserveSig.Value) - { - implFlags |= MethodImplAttributes.PreserveSig; - } - if (setLastError.HasValue && setLastError.Value) - { - flags |= SupportsLastError; - } - ImplMapTable.Record rec = new ImplMapTable.Record(); - rec.MappingFlags = flags; - rec.MemberForwarded = pseudoToken; - rec.ImportName = this.ModuleBuilder.Strings.Add(entryName ?? name); - rec.ImportScope = this.ModuleBuilder.ModuleRef.FindOrAddRecord(dllName == null ? 0 : this.ModuleBuilder.Strings.Add(dllName)); - this.ModuleBuilder.ImplMap.AddRecord(rec); - } - - private void SetMethodImplAttribute(CustomAttributeBuilder customBuilder) - { - MethodImplOptions opt; - switch (customBuilder.Constructor.ParameterCount) - { - case 0: - opt = 0; - break; - case 1: - { - object val = customBuilder.GetConstructorArgument(0); - if (val is short) - { - opt = (MethodImplOptions)(short)val; - } - else if (val is int) - { - opt = (MethodImplOptions)(int)val; - } - else - { - opt = (MethodImplOptions)val; - } - break; - } - default: - throw new NotSupportedException(); - } - MethodCodeType? type = customBuilder.GetFieldValue("MethodCodeType"); - implFlags = (MethodImplAttributes)opt; - if (type.HasValue) - { - implFlags |= (MethodImplAttributes)type; - } - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - Universe u = this.ModuleBuilder.universe; - Type type = customBuilder.Constructor.DeclaringType; - if (type == u.System_Runtime_InteropServices_DllImportAttribute) - { - attributes |= MethodAttributes.PinvokeImpl; - SetDllImportPseudoCustomAttribute(customBuilder.DecodeBlob(this.Module.Assembly)); - } - else if (type == u.System_Runtime_CompilerServices_MethodImplAttribute) - { - SetMethodImplAttribute(customBuilder.DecodeBlob(this.Module.Assembly)); - } - else if (type == u.System_Runtime_InteropServices_PreserveSigAttribute) - { - implFlags |= MethodImplAttributes.PreserveSig; - } - else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute) - { - attributes |= MethodAttributes.SpecialName; - } - else - { - if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute) - { - attributes |= MethodAttributes.HasSecurity; - } - this.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder); - } - } - - public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) - { - attributes |= MethodAttributes.HasSecurity; - if (declarativeSecurity == null) - { - declarativeSecurity = new List(); - } - declarativeSecurity.Add(customBuilder); - } - - public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet) - { - this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, securityAction, permissionSet); - this.attributes |= MethodAttributes.HasSecurity; - } - - public void SetImplementationFlags(MethodImplAttributes attributes) - { - implFlags = attributes; - } - - public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string strParamName) - { - if (parameters == null) - { - parameters = new List(); - } - this.ModuleBuilder.Param.AddVirtualRecord(); - ParameterBuilder pb = new ParameterBuilder(this.ModuleBuilder, position, attributes, strParamName); - if (parameters.Count == 0 || position > parameters[parameters.Count - 1].Position) - { - parameters.Add(pb); - } - else - { - for (int i = 0; i < parameters.Count; i++) - { - if (parameters[i].Position > position) - { - parameters.Insert(i, pb); - break; - } - } - } - return pb; - } - - private void CheckSig() - { - if (methodSignature != null) - { - throw new InvalidOperationException("The method signature can not be modified after it has been used."); - } - } - - public void SetParameters(params Type[] parameterTypes) - { - CheckSig(); - this.parameterTypes = Util.Copy(parameterTypes); - } - - public void SetReturnType(Type returnType) - { - CheckSig(); - this.returnType = returnType ?? this.Module.universe.System_Void; - } - - public void SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - SetSignature(returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, - parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - public void __SetSignature(Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - SetSignature(returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - private void SetSignature(Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) - { - CheckSig(); - this.returnType = returnType ?? this.Module.universe.System_Void; - this.parameterTypes = Util.Copy(parameterTypes); - this.customModifiers = customModifiers; - } - - public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) - { - CheckSig(); - gtpb = new GenericTypeParameterBuilder[names.Length]; - for (int i = 0; i < names.Length; i++) - { - gtpb[i] = new GenericTypeParameterBuilder(names[i], null, this, i); - } - return (GenericTypeParameterBuilder[])gtpb.Clone(); - } - - public override MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - return new GenericMethodInstance(typeBuilder, this, typeArguments); - } - - public override MethodInfo GetGenericMethodDefinition() - { - if (gtpb == null) - { - throw new InvalidOperationException(); - } - return this; - } - - public override Type[] GetGenericArguments() - { - return Util.Copy(gtpb); - } - - internal override Type GetGenericMethodArgument(int index) - { - return gtpb[index]; - } - - internal override int GetGenericMethodArgumentCount() - { - return gtpb == null ? 0 : gtpb.Length; - } - - public override Type ReturnType - { - get { return returnType; } - } - - public override ParameterInfo ReturnParameter - { - get { return new ParameterInfoImpl(this, -1); } - } - - public override MethodAttributes Attributes - { - get { return attributes; } - } - - public void __SetAttributes(MethodAttributes attributes) - { - this.attributes = attributes; - } - - public void __SetCallingConvention(CallingConventions callingConvention) - { - this.callingConvention = callingConvention; - this.methodSignature = null; - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return implFlags; - } - - private sealed class ParameterInfoImpl : ParameterInfo - { - private readonly MethodBuilder method; - private readonly int parameter; - - internal ParameterInfoImpl(MethodBuilder method, int parameter) - { - this.method = method; - this.parameter = parameter; - } - - private ParameterBuilder ParameterBuilder - { - get - { - if (method.parameters != null) - { - foreach (ParameterBuilder pb in method.parameters) - { - // ParameterBuilder.Position is 1-based - if (pb.Position - 1 == parameter) - { - return pb; - } - } - } - return null; - } - } - - public override string Name - { - get - { - ParameterBuilder pb = this.ParameterBuilder; - return pb != null ? pb.Name : null; - } - } - - public override Type ParameterType - { - get { return parameter == -1 ? method.returnType : method.parameterTypes[parameter]; } - } - - public override ParameterAttributes Attributes - { - get - { - ParameterBuilder pb = this.ParameterBuilder; - return pb != null ? (ParameterAttributes)pb.Attributes : ParameterAttributes.None; - } - } - - public override int Position - { - get { return parameter; } - } - - public override object RawDefaultValue - { - get - { - ParameterBuilder pb = this.ParameterBuilder; - if (pb != null && (pb.Attributes & (int)ParameterAttributes.HasDefault) != 0) - { - return method.ModuleBuilder.Constant.GetRawConstantValue(method.ModuleBuilder, pb.PseudoToken); - } - if (pb != null && (pb.Attributes & (int)ParameterAttributes.Optional) != 0) - { - return Missing.Value; - } - return null; - } - } - - public override CustomModifiers __GetCustomModifiers() - { - return method.customModifiers.GetParameterCustomModifiers(parameter); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - fieldMarshal = new FieldMarshal(); - return false; - } - - public override MemberInfo Member - { - get { return method; } - } - - public override int MetadataToken - { - get - { - ParameterBuilder pb = this.ParameterBuilder; - return pb != null ? pb.PseudoToken : 0x08000000; - } - } - - internal override Module Module - { - get { return method.Module; } - } - } - - public override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length]; - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoImpl(this, i); - } - return parameters; - } - - internal override int ParameterCount - { - get { return parameterTypes.Length; } - } - - public override Type DeclaringType - { - get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; } - } - - public override string Name - { - get { return name; } - } - - public override CallingConventions CallingConvention - { - get { return callingConvention; } - } - - public override int MetadataToken - { - get { return pseudoToken; } - } - - public override bool IsGenericMethod - { - get { return gtpb != null; } - } - - public override bool IsGenericMethodDefinition - { - get { return gtpb != null; } - } - - public override Module Module - { - get { return typeBuilder.Module; } - } - - public Module GetModule() - { - return typeBuilder.Module; - } - - public MethodToken GetToken() - { - return new MethodToken(pseudoToken); - } - - public override MethodBody GetMethodBody() - { - throw new NotSupportedException(); - } - - public override int __MethodRVA - { - get { throw new NotImplementedException(); } - } - - public bool InitLocals - { - get { return initLocals; } - set { initLocals = value; } - } - - public void __AddUnmanagedExport(string name, int ordinal) - { - this.ModuleBuilder.AddUnmanagedExport(name, ordinal, this, new RelativeVirtualAddress(0xFFFFFFFF)); - } - - internal void Bake() - { - this.nameIndex = this.ModuleBuilder.Strings.Add(name); - this.signature = this.ModuleBuilder.GetSignatureBlobIndex(this.MethodSignature); - - __ReleaseILGenerator(); - - if (declarativeSecurity != null) - { - this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity); - } - } - - internal ModuleBuilder ModuleBuilder - { - get { return typeBuilder.ModuleBuilder; } - } - - internal void WriteMethodDefRecord(int baseRVA, MetadataWriter mw, ref int paramList) - { - if (rva != -1) - { - mw.Write(rva + baseRVA); - } - else - { - mw.Write(0); - } - mw.Write((short)implFlags); - mw.Write((short)attributes); - mw.WriteStringIndex(nameIndex); - mw.WriteBlobIndex(signature); - mw.WriteParam(paramList); - if (parameters != null) - { - paramList += parameters.Count; - } - } - - internal void WriteParamRecords(MetadataWriter mw) - { - if (parameters != null) - { - foreach (ParameterBuilder pb in parameters) - { - pb.WriteParamRecord(mw); - } - } - } - - internal void FixupToken(int token, ref int parameterToken) - { - typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token); - if (parameters != null) - { - foreach (ParameterBuilder pb in parameters) - { - pb.FixupToken(parameterToken++); - } - } - } - - internal override MethodSignature MethodSignature - { - get - { - if (methodSignature == null) - { - methodSignature = MethodSignature.MakeFromBuilder(returnType, parameterTypes, customModifiers, callingConvention, gtpb == null ? 0 : gtpb.Length); - } - return methodSignature; - } - } - - internal override int ImportTo(ModuleBuilder other) - { - return other.ImportMethodOrField(typeBuilder, name, this.MethodSignature); - } - - internal void CheckBaked() - { - typeBuilder.CheckBaked(); - } - - internal override int GetCurrentToken() - { - if (typeBuilder.ModuleBuilder.IsSaved) - { - return typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken); - } - else - { - return pseudoToken; - } - } - - internal override bool IsBaked - { - get { return typeBuilder.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs b/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs deleted file mode 100644 index 8ffe17ba957..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/ModuleBuilder.cs +++ /dev/null @@ -1,1882 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Diagnostics; -using System.Diagnostics.SymbolStore; -using System.Security.Cryptography; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using IKVM.Reflection.Impl; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class ModuleBuilder : Module, ITypeOwner - { - private static readonly bool usePublicKeyAssemblyReference = false; - private Guid mvid = Guid.NewGuid(); - private long imageBaseAddress = 0x00400000; - private long stackReserve = -1; - private int fileAlignment = 0x200; - private DllCharacteristics dllCharacteristics = DllCharacteristics.DynamicBase | DllCharacteristics.NoSEH | DllCharacteristics.NXCompat | DllCharacteristics.TerminalServerAware; - private readonly AssemblyBuilder asm; - internal readonly string moduleName; - internal readonly string fileName; - internal readonly ISymbolWriterImpl symbolWriter; - private readonly TypeBuilder moduleType; - private readonly List types = new List(); - private readonly Dictionary typeTokens = new Dictionary(); - private readonly Dictionary memberRefTypeTokens = new Dictionary(); - internal readonly ByteBuffer methodBodies = new ByteBuffer(128 * 1024); - internal readonly List tokenFixupOffsets = new List(); - internal readonly ByteBuffer initializedData = new ByteBuffer(512); - internal readonly ByteBuffer manifestResources = new ByteBuffer(512); - internal ResourceSection unmanagedResources; - private readonly Dictionary importedMemberRefs = new Dictionary(); - private readonly Dictionary importedMethodSpecs = new Dictionary(); - private readonly Dictionary referencedAssemblies = new Dictionary(); - private List referencedAssemblyNames; - private int nextPseudoToken = -1; - private readonly List resolvedTokens = new List(); - internal readonly TableHeap Tables = new TableHeap(); - internal readonly StringHeap Strings = new StringHeap(); - internal readonly UserStringHeap UserStrings = new UserStringHeap(); - internal readonly GuidHeap Guids = new GuidHeap(); - internal readonly BlobHeap Blobs = new BlobHeap(); - internal readonly List vtablefixups = new List(); - internal readonly List unmanagedExports = new List(); - private List interfaceImplCustomAttributes; - private List resourceWriters; - private bool saved; - - private struct ResourceWriterRecord - { - private readonly string name; - private readonly ResourceWriter rw; - private readonly MemoryStream mem; - private readonly ResourceAttributes attributes; - - internal ResourceWriterRecord(string name, ResourceWriter rw, MemoryStream mem, ResourceAttributes attributes) - { - this.name = name; - this.rw = rw; - this.mem = mem; - this.attributes = attributes; - } - - internal void Emit(ModuleBuilder mb) - { - rw.Generate(); - mem.Position = 0; - mb.DefineManifestResource(name, mem, attributes); - rw.Close(); - } - } - - internal struct VTableFixups - { - internal uint initializedDataOffset; - internal ushort count; - internal ushort type; - - internal int SlotWidth - { - get { return (type & 0x02) == 0 ? 4 : 8; } - } - } - - struct InterfaceImplCustomAttribute - { - internal int type; - internal int interfaceType; - internal int pseudoToken; - } - - struct MemberRefKey : IEquatable - { - private readonly Type type; - private readonly string name; - private readonly Signature signature; - - internal MemberRefKey(Type type, string name, Signature signature) - { - this.type = type; - this.name = name; - this.signature = signature; - } - - public bool Equals(MemberRefKey other) - { - return other.type.Equals(type) - && other.name == name - && other.signature.Equals(signature); - } - - public override bool Equals(object obj) - { - MemberRefKey? other = obj as MemberRefKey?; - return other != null && Equals(other); - } - - public override int GetHashCode() - { - return type.GetHashCode() + name.GetHashCode() + signature.GetHashCode(); - } - - internal MethodBase LookupMethod() - { - return type.FindMethod(name, (MethodSignature)signature); - } - } - - struct MethodSpecKey : IEquatable - { - private readonly Type type; - private readonly string name; - private readonly MethodSignature signature; - private readonly Type[] genericParameters; - - internal MethodSpecKey(Type type, string name, MethodSignature signature, Type[] genericParameters) - { - this.type = type; - this.name = name; - this.signature = signature; - this.genericParameters = genericParameters; - } - - public bool Equals(MethodSpecKey other) - { - return other.type.Equals(type) - && other.name == name - && other.signature.Equals(signature) - && Util.ArrayEquals(other.genericParameters, genericParameters); - } - - public override bool Equals(object obj) - { - MethodSpecKey? other = obj as MethodSpecKey?; - return other != null && Equals(other); - } - - public override int GetHashCode() - { - return type.GetHashCode() + name.GetHashCode() + signature.GetHashCode() + Util.GetHashCode(genericParameters); - } - } - - internal ModuleBuilder(AssemblyBuilder asm, string moduleName, string fileName, bool emitSymbolInfo) - : base(asm.universe) - { - this.asm = asm; - this.moduleName = moduleName; - this.fileName = fileName; - if (emitSymbolInfo) - { - symbolWriter = SymbolSupport.CreateSymbolWriterFor(this); - } - // must be the first record in the TypeDef table - moduleType = new TypeBuilder(this, null, ""); - types.Add(moduleType); - } - - internal void PopulatePropertyAndEventTables() - { - // LAMESPEC the PropertyMap and EventMap tables are not required to be sorted by the CLI spec, - // but .NET sorts them and Mono requires them to be sorted, so we have to populate the - // tables in the right order - foreach (TypeBuilder type in types) - { - type.PopulatePropertyAndEventTables(); - } - } - - internal void WriteTypeDefTable(MetadataWriter mw) - { - int fieldList = 1; - int methodList = 1; - foreach (TypeBuilder type in types) - { - type.WriteTypeDefRecord(mw, ref fieldList, ref methodList); - } - } - - internal void WriteMethodDefTable(int baseRVA, MetadataWriter mw) - { - int paramList = 1; - foreach (TypeBuilder type in types) - { - type.WriteMethodDefRecords(baseRVA, mw, ref paramList); - } - } - - internal void WriteParamTable(MetadataWriter mw) - { - foreach (TypeBuilder type in types) - { - type.WriteParamRecords(mw); - } - } - - internal void WriteFieldTable(MetadataWriter mw) - { - foreach (TypeBuilder type in types) - { - type.WriteFieldRecords(mw); - } - } - - internal int AllocPseudoToken() - { - return nextPseudoToken--; - } - - public TypeBuilder DefineType(string name) - { - return DefineType(name, TypeAttributes.Class); - } - - public TypeBuilder DefineType(string name, TypeAttributes attr) - { - return DefineType(name, attr, null); - } - - public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent) - { - return DefineType(name, attr, parent, PackingSize.Unspecified, 0); - } - - public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, int typesize) - { - return DefineType(name, attr, parent, PackingSize.Unspecified, typesize); - } - - public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, PackingSize packsize) - { - return DefineType(name, attr, parent, packsize, 0); - } - - public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, Type[] interfaces) - { - TypeBuilder tb = DefineType(name, attr, parent); - foreach (Type iface in interfaces) - { - tb.AddInterfaceImplementation(iface); - } - return tb; - } - - public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) - { - string ns = null; - int lastdot = name.LastIndexOf('.'); - if (lastdot > 0) - { - ns = name.Substring(0, lastdot); - name = name.Substring(lastdot + 1); - } - TypeBuilder typeBuilder = __DefineType(ns, name); - typeBuilder.__SetAttributes(attr); - typeBuilder.SetParent(parent); - if (packingSize != PackingSize.Unspecified || typesize != 0) - { - typeBuilder.__SetLayout((int)packingSize, typesize); - } - return typeBuilder; - } - - public TypeBuilder __DefineType(string ns, string name) - { - return DefineType(this, ns, name); - } - - internal TypeBuilder DefineType(ITypeOwner owner, string ns, string name) - { - TypeBuilder typeBuilder = new TypeBuilder(owner, ns, name); - types.Add(typeBuilder); - return typeBuilder; - } - - public EnumBuilder DefineEnum(string name, TypeAttributes visibility, Type underlyingType) - { - TypeBuilder tb = DefineType(name, (visibility & TypeAttributes.VisibilityMask) | TypeAttributes.Sealed, universe.System_Enum); - FieldBuilder fb = tb.DefineField("value__", underlyingType, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); - return new EnumBuilder(tb, fb); - } - - public FieldBuilder __DefineField(string name, Type type, CustomModifiers customModifiers, FieldAttributes attributes) - { - return moduleType.__DefineField(name, type, customModifiers, attributes); - } - - [Obsolete("Please use __DefineField(string, Type, CustomModifiers, FieldAttributes) instead.")] - public FieldBuilder __DefineField(string name, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) - { - return moduleType.DefineField(name, type, requiredCustomModifiers, optionalCustomModifiers, attributes); - } - - public ConstructorBuilder __DefineModuleInitializer(MethodAttributes visibility) - { - return moduleType.DefineConstructor(visibility | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, Type.EmptyTypes); - } - - public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes) - { - return moduleType.DefineUninitializedData(name, size, attributes); - } - - public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes) - { - return moduleType.DefineInitializedData(name, data, attributes); - } - - public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) - { - return moduleType.DefineMethod(name, attributes, returnType, parameterTypes); - } - - public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - { - return moduleType.DefineMethod(name, attributes, callingConvention, returnType, parameterTypes); - } - - public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) - { - return moduleType.DefineMethod(name, attributes, callingConvention, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); - } - - public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) - { - return moduleType.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); - } - - public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) - { - return moduleType.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); - } - - public void CreateGlobalFunctions() - { - moduleType.CreateType(); - } - - internal void AddTypeForwarder(Type type) - { - ExportType(type); - if (!type.__IsMissing) - { - foreach (Type nested in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)) - { - // we export all nested types (i.e. even the private ones) - // (this behavior is the same as the C# compiler) - AddTypeForwarder(nested); - } - } - } - - private int ExportType(Type type) - { - ExportedTypeTable.Record rec = new ExportedTypeTable.Record(); - rec.TypeDefId = type.MetadataToken; - rec.TypeName = this.Strings.Add(type.__Name); - string ns = type.__Namespace; - rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(ns); - if (type.IsNested) - { - rec.Flags = 0; - rec.Implementation = ExportType(type.DeclaringType); - } - else - { - rec.Flags = 0x00200000; // CorTypeAttr.tdForwarder - rec.Implementation = ImportAssemblyRef(type.Assembly); - } - return 0x27000000 | this.ExportedType.FindOrAddRecord(rec); - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - SetCustomAttribute(0x00000001, customBuilder); - } - - internal void SetCustomAttribute(int token, CustomAttributeBuilder customBuilder) - { - Debug.Assert(!customBuilder.IsPseudoCustomAttribute); - CustomAttributeTable.Record rec = new CustomAttributeTable.Record(); - rec.Parent = token; - rec.Type = asm.IsWindowsRuntime ? customBuilder.Constructor.ImportTo(this) : GetConstructorToken(customBuilder.Constructor).Token; - rec.Value = customBuilder.WriteBlob(this); - this.CustomAttribute.AddRecord(rec); - } - - internal void AddDeclarativeSecurity(int token, System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet) - { - DeclSecurityTable.Record rec = new DeclSecurityTable.Record(); - rec.Action = (short)securityAction; - rec.Parent = token; - // like Ref.Emit, we're using the .NET 1.x xml format - rec.PermissionSet = this.Blobs.Add(ByteBuffer.Wrap(System.Text.Encoding.Unicode.GetBytes(permissionSet.ToXml().ToString()))); - this.DeclSecurity.AddRecord(rec); - } - - internal void AddDeclarativeSecurity(int token, List declarativeSecurity) - { - Dictionary> ordered = new Dictionary>(); - foreach (CustomAttributeBuilder cab in declarativeSecurity) - { - int action; - // check for HostProtectionAttribute without SecurityAction - if (cab.ConstructorArgumentCount == 0) - { - action = (int)System.Security.Permissions.SecurityAction.LinkDemand; - } - else - { - action = (int)cab.GetConstructorArgument(0); - } - List list; - if (!ordered.TryGetValue(action, out list)) - { - list = new List(); - ordered.Add(action, list); - } - list.Add(cab); - } - foreach (KeyValuePair> kv in ordered) - { - DeclSecurityTable.Record rec = new DeclSecurityTable.Record(); - rec.Action = (short)kv.Key; - rec.Parent = token; - rec.PermissionSet = WriteDeclSecurityBlob(kv.Value); - this.DeclSecurity.AddRecord(rec); - } - } - - private int WriteDeclSecurityBlob(List list) - { - string xml; - if (list.Count == 1 && (xml = list[0].GetLegacyDeclSecurity()) != null) - { - // write .NET 1.1 format - return this.Blobs.Add(ByteBuffer.Wrap(System.Text.Encoding.Unicode.GetBytes(xml))); - } - ByteBuffer namedArgs = new ByteBuffer(100); - ByteBuffer bb = new ByteBuffer(list.Count * 100); - bb.Write((byte)'.'); - bb.WriteCompressedInt(list.Count); - foreach (CustomAttributeBuilder cab in list) - { - bb.Write(cab.Constructor.DeclaringType.AssemblyQualifiedName); - namedArgs.Clear(); - cab.WriteNamedArgumentsForDeclSecurity(this, namedArgs); - bb.WriteCompressedInt(namedArgs.Length); - bb.Write(namedArgs); - } - return this.Blobs.Add(bb); - } - - public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute) - { - manifestResources.Align(8); - ManifestResourceTable.Record rec = new ManifestResourceTable.Record(); - rec.Offset = manifestResources.Position; - rec.Flags = (int)attribute; - rec.Name = this.Strings.Add(name); - rec.Implementation = 0; - this.ManifestResource.AddRecord(rec); - manifestResources.Write(0); // placeholder for the length - manifestResources.Write(stream); - int savePosition = manifestResources.Position; - manifestResources.Position = rec.Offset; - manifestResources.Write(savePosition - (manifestResources.Position + 4)); - manifestResources.Position = savePosition; - } - - public IResourceWriter DefineResource(string name, string description) - { - return DefineResource(name, description, ResourceAttributes.Public); - } - - public IResourceWriter DefineResource(string name, string description, ResourceAttributes attribute) - { - // FXBUG we ignore the description, because there is no such thing - - if (resourceWriters == null) - { - resourceWriters = new List(); - } - MemoryStream mem = new MemoryStream(); - ResourceWriter rw = new ResourceWriter(mem); - resourceWriters.Add(new ResourceWriterRecord(name, rw, mem, attribute)); - return rw; - } - - internal void EmitResources() - { - if (resourceWriters != null) - { - foreach (ResourceWriterRecord rwr in resourceWriters) - { - rwr.Emit(this); - } - } - } - - public override Assembly Assembly - { - get { return asm; } - } - - internal override Type FindType(TypeName name) - { - foreach (Type type in types) - { - if (type.__Namespace == name.Namespace && type.__Name == name.Name) - { - return type; - } - } - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - foreach (Type type in types) - { - if (new TypeName(type.__Namespace, type.__Name).ToLowerInvariant() == lowerCaseName) - { - return type; - } - } - return null; - } - - internal override void GetTypesImpl(List list) - { - foreach (Type type in types) - { - if (type != moduleType) - { - list.Add(type); - } - } - } - - public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) - { - return symbolWriter.DefineDocument(url, language, languageVendor, documentType); - } - - public int __GetAssemblyToken(Assembly assembly) - { - return ImportAssemblyRef(assembly); - } - - public TypeToken GetTypeToken(string name) - { - return new TypeToken(GetType(name, true, false).MetadataToken); - } - - public TypeToken GetTypeToken(Type type) - { - if (type.Module == this && !asm.IsWindowsRuntime) - { - return new TypeToken(type.GetModuleBuilderToken()); - } - else - { - return new TypeToken(ImportType(type)); - } - } - - internal int GetTypeTokenForMemberRef(Type type) - { - if (type.__IsMissing) - { - return ImportType(type); - } - else if (type.IsGenericTypeDefinition) - { - int token; - if (!memberRefTypeTokens.TryGetValue(type, out token)) - { - ByteBuffer spec = new ByteBuffer(5); - Signature.WriteTypeSpec(this, spec, type); - token = 0x1B000000 | this.TypeSpec.AddRecord(this.Blobs.Add(spec)); - memberRefTypeTokens.Add(type, token); - } - return token; - } - else if (type.IsModulePseudoType) - { - return 0x1A000000 | this.ModuleRef.FindOrAddRecord(this.Strings.Add(type.Module.ScopeName)); - } - else - { - return GetTypeToken(type).Token; - } - } - - private static bool IsFromGenericTypeDefinition(MemberInfo member) - { - Type decl = member.DeclaringType; - return decl != null && !decl.__IsMissing && decl.IsGenericTypeDefinition; - } - - public FieldToken GetFieldToken(FieldInfo field) - { - // NOTE for some reason, when TypeBuilder.GetFieldToken() is used on a field in a generic type definition, - // a memberref token is returned (confirmed on .NET) unlike for Get(Method|Constructor)Token which always - // simply returns the MethodDef token (if the method is from the same module). - FieldBuilder fb = field as FieldBuilder; - if (fb != null && fb.Module == this && !IsFromGenericTypeDefinition(fb)) - { - return new FieldToken(fb.MetadataToken); - } - else - { - return new FieldToken(field.ImportTo(this)); - } - } - - public MethodToken GetMethodToken(MethodInfo method) - { - MethodBuilder mb = method as MethodBuilder; - if (mb != null && mb.ModuleBuilder == this) - { - return new MethodToken(mb.MetadataToken); - } - else - { - return new MethodToken(method.ImportTo(this)); - } - } - - // new in .NET 4.5 - public MethodToken GetMethodToken(MethodInfo method, IEnumerable optionalParameterTypes) - { - return __GetMethodToken(method, Util.ToArray(optionalParameterTypes), null); - } - - public MethodToken __GetMethodToken(MethodInfo method, Type[] optionalParameterTypes, CustomModifiers[] customModifiers) - { - ByteBuffer sig = new ByteBuffer(16); - method.MethodSignature.WriteMethodRefSig(this, sig, optionalParameterTypes, customModifiers); - MemberRefTable.Record record = new MemberRefTable.Record(); - if (method.Module == this) - { - record.Class = method.MetadataToken; - } - else - { - record.Class = GetTypeTokenForMemberRef(method.DeclaringType ?? method.Module.GetModuleType()); - } - record.Name = Strings.Add(method.Name); - record.Signature = Blobs.Add(sig); - return new MethodToken(0x0A000000 | MemberRef.FindOrAddRecord(record)); - } - - // when we refer to a method on a generic type definition in the IL stream, - // we need to use a MemberRef (even if the method is in the same module) - internal MethodToken GetMethodTokenForIL(MethodInfo method) - { - if (method.IsGenericMethodDefinition) - { - method = method.MakeGenericMethod(method.GetGenericArguments()); - } - if (IsFromGenericTypeDefinition(method)) - { - return new MethodToken(method.ImportTo(this)); - } - else - { - return GetMethodToken(method); - } - } - - internal int GetMethodTokenWinRT(MethodInfo method) - { - return asm.IsWindowsRuntime ? method.ImportTo(this) : GetMethodToken(method).Token; - } - - public MethodToken GetConstructorToken(ConstructorInfo constructor) - { - return GetMethodToken(constructor.GetMethodInfo()); - } - - // new in .NET 4.5 - public MethodToken GetConstructorToken(ConstructorInfo constructor, IEnumerable optionalParameterTypes) - { - return GetMethodToken(constructor.GetMethodInfo(), optionalParameterTypes); - } - - public MethodToken __GetConstructorToken(ConstructorInfo constructor, Type[] optionalParameterTypes, CustomModifiers[] customModifiers) - { - return __GetMethodToken(constructor.GetMethodInfo(), optionalParameterTypes, customModifiers); - } - - internal int ImportMethodOrField(Type declaringType, string name, Signature sig) - { - int token; - MemberRefKey key = new MemberRefKey(declaringType, name, sig); - if (!importedMemberRefs.TryGetValue(key, out token)) - { - MemberRefTable.Record rec = new MemberRefTable.Record(); - rec.Class = GetTypeTokenForMemberRef(declaringType); - rec.Name = this.Strings.Add(name); - ByteBuffer bb = new ByteBuffer(16); - sig.WriteSig(this, bb); - rec.Signature = this.Blobs.Add(bb); - token = 0x0A000000 | this.MemberRef.AddRecord(rec); - importedMemberRefs.Add(key, token); - } - return token; - } - - internal int ImportMethodSpec(Type declaringType, MethodInfo method, Type[] genericParameters) - { - Debug.Assert(method.__IsMissing || method.GetMethodOnTypeDefinition() == method); - int token; - MethodSpecKey key = new MethodSpecKey(declaringType, method.Name, method.MethodSignature, genericParameters); - if (!importedMethodSpecs.TryGetValue(key, out token)) - { - MethodSpecTable.Record rec = new MethodSpecTable.Record(); - MethodBuilder mb = method as MethodBuilder; - if (mb != null && mb.ModuleBuilder == this && !declaringType.IsGenericType) - { - rec.Method = mb.MetadataToken; - } - else - { - // we're calling ImportMethodOrField directly here, because 'method' may be a MethodDef on a generic TypeDef and 'declaringType' the type instance - // (in order words the method and type have already been decoupled by the caller) - rec.Method = ImportMethodOrField(declaringType, method.Name, method.MethodSignature); - } - Writer.ByteBuffer spec = new Writer.ByteBuffer(10); - Signature.WriteMethodSpec(this, spec, genericParameters); - rec.Instantiation = this.Blobs.Add(spec); - token = 0x2B000000 | this.MethodSpec.FindOrAddRecord(rec); - importedMethodSpecs.Add(key, token); - } - return token; - } - - internal int ImportType(Type type) - { - int token; - if (!typeTokens.TryGetValue(type, out token)) - { - if (type.HasElementType || type.IsConstructedGenericType || type.__IsFunctionPointer) - { - ByteBuffer spec = new ByteBuffer(5); - Signature.WriteTypeSpec(this, spec, type); - token = 0x1B000000 | this.TypeSpec.AddRecord(this.Blobs.Add(spec)); - } - else - { - TypeRefTable.Record rec = new TypeRefTable.Record(); - if (type.IsNested) - { - rec.ResolutionScope = GetTypeToken(type.DeclaringType).Token; - } - else if (type.Module == this) - { - rec.ResolutionScope = 1; - } - else - { - rec.ResolutionScope = ImportAssemblyRef(type.Assembly); - } - rec.TypeName = this.Strings.Add(type.__Name); - string ns = type.__Namespace; - rec.TypeNameSpace = ns == null ? 0 : this.Strings.Add(ns); - token = 0x01000000 | this.TypeRef.AddRecord(rec); - } - typeTokens.Add(type, token); - } - return token; - } - - private int ImportAssemblyRef(Assembly asm) - { - int token; - if (!referencedAssemblies.TryGetValue(asm, out token)) - { - // We can't write the AssemblyRef record here yet, because the identity of the assembly can still change - // (if it's an AssemblyBuilder). - token = AllocPseudoToken(); - referencedAssemblies.Add(asm, token); - } - return token; - } - - internal void FillAssemblyRefTable() - { - foreach (KeyValuePair kv in referencedAssemblies) - { - if (IsPseudoToken(kv.Value)) - { - RegisterTokenFixup(kv.Value, FindOrAddAssemblyRef(kv.Key.GetName(), false)); - } - } - } - - private int FindOrAddAssemblyRef(AssemblyName name, bool alwaysAdd) - { - AssemblyRefTable.Record rec = new AssemblyRefTable.Record(); - Version ver = name.Version ?? new Version(0, 0, 0, 0); - rec.MajorVersion = (ushort)ver.Major; - rec.MinorVersion = (ushort)ver.Minor; - rec.BuildNumber = (ushort)ver.Build; - rec.RevisionNumber = (ushort)ver.Revision; - rec.Flags = (int)(name.Flags & ~AssemblyNameFlags.PublicKey); - const AssemblyNameFlags afPA_Specified = (AssemblyNameFlags)0x0080; - const AssemblyNameFlags afPA_Mask = (AssemblyNameFlags)0x0070; - if ((name.RawFlags & afPA_Specified) != 0) - { - rec.Flags |= (int)(name.RawFlags & afPA_Mask); - } - if (name.ContentType == AssemblyContentType.WindowsRuntime) - { - rec.Flags |= 0x0200; - } - byte[] publicKeyOrToken = null; - if (usePublicKeyAssemblyReference) - { - publicKeyOrToken = name.GetPublicKey(); - } - if (publicKeyOrToken == null || publicKeyOrToken.Length == 0) - { - publicKeyOrToken = name.GetPublicKeyToken() ?? Empty.Array; - } - else - { - const int PublicKey = 0x0001; - rec.Flags |= PublicKey; - } - rec.PublicKeyOrToken = this.Blobs.Add(ByteBuffer.Wrap(publicKeyOrToken)); - rec.Name = this.Strings.Add(name.Name); - rec.Culture = name.Culture == null ? 0 : this.Strings.Add(name.Culture); - if (name.hash != null) - { - rec.HashValue = this.Blobs.Add(ByteBuffer.Wrap(name.hash)); - } - else - { - rec.HashValue = 0; - } - return 0x23000000 | (alwaysAdd ? this.AssemblyRef.AddRecord(rec) : this.AssemblyRef.FindOrAddRecord(rec)); - } - - internal void WriteSymbolTokenMap() - { - for (int i = 0; i < resolvedTokens.Count; i++) - { - int newToken = resolvedTokens[i]; - // The symbol API doesn't support remapping arbitrary integers, the types have to be the same, - // so we copy the type from the newToken, because our pseudo tokens don't have a type. - // (see MethodToken.SymbolToken) - int oldToken = (i + 1) | (newToken & ~0xFFFFFF); - SymbolSupport.RemapToken(symbolWriter, oldToken, newToken); - } - } - - internal void RegisterTokenFixup(int pseudoToken, int realToken) - { - int index = -(pseudoToken + 1); - while (resolvedTokens.Count <= index) - { - resolvedTokens.Add(0); - } - resolvedTokens[index] = realToken; - } - - internal bool IsPseudoToken(int token) - { - return token < 0; - } - - internal int ResolvePseudoToken(int pseudoToken) - { - int index = -(pseudoToken + 1); - return resolvedTokens[index]; - } - - internal void ApplyUnmanagedExports(ImageFileMachine imageFileMachine) - { - if (unmanagedExports.Count != 0) - { - int type; - int size; - if (imageFileMachine == ImageFileMachine.I386) - { - type = 0x05; - size = 4; - } - else - { - type = 0x06; - size = 8; - } - List methods = new List(); - for (int i = 0; i < unmanagedExports.Count; i++) - { - if (unmanagedExports[i].mb != null) - { - methods.Add(unmanagedExports[i].mb); - } - } - if (methods.Count != 0) - { - RelativeVirtualAddress rva = __AddVTableFixups(methods.ToArray(), type); - for (int i = 0; i < unmanagedExports.Count; i++) - { - if (unmanagedExports[i].mb != null) - { - UnmanagedExport exp = unmanagedExports[i]; - exp.rva = new RelativeVirtualAddress(rva.initializedDataOffset + (uint)(methods.IndexOf(unmanagedExports[i].mb) * size)); - unmanagedExports[i] = exp; - } - } - } - } - } - - internal void FixupMethodBodyTokens() - { - int methodToken = 0x06000001; - int fieldToken = 0x04000001; - int parameterToken = 0x08000001; - foreach (TypeBuilder type in types) - { - type.ResolveMethodAndFieldTokens(ref methodToken, ref fieldToken, ref parameterToken); - } - foreach (int offset in tokenFixupOffsets) - { - methodBodies.Position = offset; - int pseudoToken = methodBodies.GetInt32AtCurrentPosition(); - methodBodies.Write(ResolvePseudoToken(pseudoToken)); - } - foreach (VTableFixups fixup in vtablefixups) - { - for (int i = 0; i < fixup.count; i++) - { - initializedData.Position = (int)fixup.initializedDataOffset + i * fixup.SlotWidth; - initializedData.Write(ResolvePseudoToken(initializedData.GetInt32AtCurrentPosition())); - } - } - } - - private int GetHeaderLength() - { - return - 4 + // Signature - 2 + // MajorVersion - 2 + // MinorVersion - 4 + // Reserved - 4 + // ImageRuntimeVersion Length - StringToPaddedUTF8Length(asm.ImageRuntimeVersion) + - 2 + // Flags - 2 + // Streams - 4 + // #~ Offset - 4 + // #~ Size - 4 + // StringToPaddedUTF8Length("#~") - 4 + // #Strings Offset - 4 + // #Strings Size - 12 + // StringToPaddedUTF8Length("#Strings") - 4 + // #US Offset - 4 + // #US Size - 4 + // StringToPaddedUTF8Length("#US") - 4 + // #GUID Offset - 4 + // #GUID Size - 8 + // StringToPaddedUTF8Length("#GUID") - (Blobs.IsEmpty ? 0 : - ( - 4 + // #Blob Offset - 4 + // #Blob Size - 8 // StringToPaddedUTF8Length("#Blob") - )); - } - - internal int MetadataLength - { - get - { - return GetHeaderLength() + (Blobs.IsEmpty ? 0 : Blobs.Length) + Tables.Length + Strings.Length + UserStrings.Length + Guids.Length; - } - } - - internal void WriteMetadata(MetadataWriter mw) - { - mw.Write(0x424A5342); // Signature ("BSJB") - mw.Write((ushort)1); // MajorVersion - mw.Write((ushort)1); // MinorVersion - mw.Write(0); // Reserved - byte[] version = StringToPaddedUTF8(asm.ImageRuntimeVersion); - mw.Write(version.Length); // Length - mw.Write(version); - mw.Write((ushort)0); // Flags - // #Blob is the only optional heap - if (Blobs.IsEmpty) - { - mw.Write((ushort)4); // Streams - } - else - { - mw.Write((ushort)5); // Streams - } - - int offset = GetHeaderLength(); - - // Streams - mw.Write(offset); // Offset - mw.Write(Tables.Length); // Size - mw.Write(StringToPaddedUTF8("#~")); - offset += Tables.Length; - - mw.Write(offset); // Offset - mw.Write(Strings.Length); // Size - mw.Write(StringToPaddedUTF8("#Strings")); - offset += Strings.Length; - - mw.Write(offset); // Offset - mw.Write(UserStrings.Length); // Size - mw.Write(StringToPaddedUTF8("#US")); - offset += UserStrings.Length; - - mw.Write(offset); // Offset - mw.Write(Guids.Length); // Size - mw.Write(StringToPaddedUTF8("#GUID")); - offset += Guids.Length; - - if (!Blobs.IsEmpty) - { - mw.Write(offset); // Offset - mw.Write(Blobs.Length); // Size - mw.Write(StringToPaddedUTF8("#Blob")); - } - - Tables.Write(mw); - Strings.Write(mw); - UserStrings.Write(mw); - Guids.Write(mw); - if (!Blobs.IsEmpty) - { - Blobs.Write(mw); - } - } - - private static int StringToPaddedUTF8Length(string str) - { - return (System.Text.Encoding.UTF8.GetByteCount(str) + 4) & ~3; - } - - private static byte[] StringToPaddedUTF8(string str) - { - byte[] buf = new byte[(System.Text.Encoding.UTF8.GetByteCount(str) + 4) & ~3]; - System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, buf, 0); - return buf; - } - - internal override void ExportTypes(int fileToken, ModuleBuilder manifestModule) - { - manifestModule.ExportTypes(types.ToArray(), fileToken); - } - - internal void ExportTypes(Type[] types, int fileToken) - { - Dictionary declaringTypes = new Dictionary(); - foreach (Type type in types) - { - if (!type.IsModulePseudoType && IsVisible(type)) - { - ExportedTypeTable.Record rec = new ExportedTypeTable.Record(); - rec.Flags = (int)type.Attributes; - // LAMESPEC ECMA says that TypeDefId is a row index, but it should be a token - rec.TypeDefId = type.MetadataToken; - rec.TypeName = this.Strings.Add(type.__Name); - string ns = type.__Namespace; - rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(ns); - if (type.IsNested) - { - rec.Implementation = declaringTypes[type.DeclaringType]; - } - else - { - rec.Implementation = fileToken; - } - int exportTypeToken = 0x27000000 | this.ExportedType.AddRecord(rec); - declaringTypes.Add(type, exportTypeToken); - } - } - } - - private static bool IsVisible(Type type) - { - // NOTE this is not the same as Type.IsVisible, because that doesn't take into account family access - return type.IsPublic || ((type.IsNestedFamily || type.IsNestedFamORAssem || type.IsNestedPublic) && IsVisible(type.DeclaringType)); - } - - internal void AddConstant(int parentToken, object defaultValue) - { - ConstantTable.Record rec = new ConstantTable.Record(); - rec.Parent = parentToken; - ByteBuffer val = new ByteBuffer(16); - if (defaultValue == null) - { - rec.Type = Signature.ELEMENT_TYPE_CLASS; - val.Write((int)0); - } - else if (defaultValue is bool) - { - rec.Type = Signature.ELEMENT_TYPE_BOOLEAN; - val.Write((bool)defaultValue ? (byte)1 : (byte)0); - } - else if (defaultValue is char) - { - rec.Type = Signature.ELEMENT_TYPE_CHAR; - val.Write((char)defaultValue); - } - else if (defaultValue is sbyte) - { - rec.Type = Signature.ELEMENT_TYPE_I1; - val.Write((sbyte)defaultValue); - } - else if (defaultValue is byte) - { - rec.Type = Signature.ELEMENT_TYPE_U1; - val.Write((byte)defaultValue); - } - else if (defaultValue is short) - { - rec.Type = Signature.ELEMENT_TYPE_I2; - val.Write((short)defaultValue); - } - else if (defaultValue is ushort) - { - rec.Type = Signature.ELEMENT_TYPE_U2; - val.Write((ushort)defaultValue); - } - else if (defaultValue is int) - { - rec.Type = Signature.ELEMENT_TYPE_I4; - val.Write((int)defaultValue); - } - else if (defaultValue is uint) - { - rec.Type = Signature.ELEMENT_TYPE_U4; - val.Write((uint)defaultValue); - } - else if (defaultValue is long) - { - rec.Type = Signature.ELEMENT_TYPE_I8; - val.Write((long)defaultValue); - } - else if (defaultValue is ulong) - { - rec.Type = Signature.ELEMENT_TYPE_U8; - val.Write((ulong)defaultValue); - } - else if (defaultValue is float) - { - rec.Type = Signature.ELEMENT_TYPE_R4; - val.Write((float)defaultValue); - } - else if (defaultValue is double) - { - rec.Type = Signature.ELEMENT_TYPE_R8; - val.Write((double)defaultValue); - } - else if (defaultValue is string) - { - rec.Type = Signature.ELEMENT_TYPE_STRING; - foreach (char c in (string)defaultValue) - { - val.Write(c); - } - } - else if (defaultValue is DateTime) - { - rec.Type = Signature.ELEMENT_TYPE_I8; - val.Write(((DateTime)defaultValue).Ticks); - } - else - { - throw new ArgumentException(); - } - rec.Value = this.Blobs.Add(val); - this.Constant.AddRecord(rec); - } - - ModuleBuilder ITypeOwner.ModuleBuilder - { - get { return this; } - } - - internal override Type ResolveType(int metadataToken, IGenericContext context) - { - if (metadataToken >> 24 != TypeDefTable.Index) - { - throw new NotImplementedException(); - } - return types[(metadataToken & 0xFFFFFF) - 1]; - } - - public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - if (genericTypeArguments != null || genericMethodArguments != null) - { - throw new NotImplementedException(); - } - // this method is inefficient, but since it isn't used we don't care - if ((metadataToken >> 24) == MemberRefTable.Index) - { - foreach (KeyValuePair kv in importedMemberRefs) - { - if (kv.Value == metadataToken) - { - return kv.Key.LookupMethod(); - } - } - } - // HACK if we're given a SymbolToken, we need to convert back - if ((metadataToken & 0xFF000000) == 0x06000000) - { - metadataToken = -(metadataToken & 0x00FFFFFF); - } - foreach (Type type in types) - { - MethodBase method = ((TypeBuilder)type).LookupMethod(metadataToken); - if (method != null) - { - return method; - } - } - return ((TypeBuilder)moduleType).LookupMethod(metadataToken); - } - - public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw new NotImplementedException(); - } - - public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw new NotImplementedException(); - } - - public override string ResolveString(int metadataToken) - { - throw new NotImplementedException(); - } - - public override string FullyQualifiedName - { - get { return Path.GetFullPath(Path.Combine(asm.dir, fileName)); } - } - - public override string Name - { - get { return fileName; } - } - - public override Guid ModuleVersionId - { - get { return mvid; } - } - - public void __SetModuleVersionId(Guid guid) - { - mvid = guid; - } - - public override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers) - { - throw new NotImplementedException(); - } - - public override string ScopeName - { - get { return moduleName; } - } - - public ISymbolWriter GetSymWriter() - { - return symbolWriter; - } - - public void DefineUnmanagedResource(string resourceFileName) - { - // This method reads the specified resource file (Win32 .res file) and converts it into the appropriate format and embeds it in the .rsrc section, - // also setting the Resource Directory entry. - unmanagedResources = new ResourceSection(); - unmanagedResources.ExtractResources(System.IO.File.ReadAllBytes(resourceFileName)); - } - - public bool IsTransient() - { - return false; - } - - public void SetUserEntryPoint(MethodInfo entryPoint) - { - int token = entryPoint.MetadataToken; - if (token < 0) - { - token = -token | 0x06000000; - } - if (symbolWriter != null) - { - symbolWriter.SetUserEntryPoint(new SymbolToken(token)); - } - } - - public StringToken GetStringConstant(string str) - { - return new StringToken(this.UserStrings.Add(str) | (0x70 << 24)); - } - - public SignatureToken GetSignatureToken(SignatureHelper sigHelper) - { - return new SignatureToken(this.StandAloneSig.FindOrAddRecord(this.Blobs.Add(sigHelper.GetSignature(this))) | (StandAloneSigTable.Index << 24)); - } - - public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength) - { - return new SignatureToken(this.StandAloneSig.FindOrAddRecord(this.Blobs.Add(ByteBuffer.Wrap(sigBytes, sigLength))) | (StandAloneSigTable.Index << 24)); - } - - public MethodInfo GetArrayMethod(Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - { - return new ArrayMethod(this, arrayClass, methodName, callingConvention, returnType, parameterTypes); - } - - public MethodToken GetArrayMethodToken(Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - { - return GetMethodToken(GetArrayMethod(arrayClass, methodName, callingConvention, returnType, parameterTypes)); - } - - internal override Type GetModuleType() - { - return moduleType; - } - - internal override IKVM.Reflection.Reader.ByteReader GetBlob(int blobIndex) - { - return Blobs.GetBlob(blobIndex); - } - - internal int GetSignatureBlobIndex(Signature sig) - { - ByteBuffer bb = new ByteBuffer(16); - sig.WriteSig(this, bb); - return this.Blobs.Add(bb); - } - - // non-standard API - public new long __ImageBase - { - get { return imageBaseAddress; } - set { imageBaseAddress = value; } - } - - protected override long GetImageBaseImpl() - { - return imageBaseAddress; - } - - public new long __StackReserve - { - get { return stackReserve; } - set { stackReserve = value; } - } - - protected override long GetStackReserveImpl() - { - return stackReserve; - } - - [Obsolete("Use __StackReserve property.")] - public void __SetStackReserve(long stackReserve) - { - __StackReserve = stackReserve; - } - - internal ulong GetStackReserve(ulong defaultValue) - { - return stackReserve == -1 ? defaultValue : (ulong)stackReserve; - } - - public new int __FileAlignment - { - get { return fileAlignment; } - set { fileAlignment = value; } - } - - protected override int GetFileAlignmentImpl() - { - return fileAlignment; - } - - public new DllCharacteristics __DllCharacteristics - { - get { return dllCharacteristics; } - set { dllCharacteristics = value; } - } - - protected override DllCharacteristics GetDllCharacteristicsImpl() - { - return dllCharacteristics; - } - - public override int MDStreamVersion - { - get { return asm.mdStreamVersion; } - } - - private int AddTypeRefByName(int resolutionScope, string ns, string name) - { - TypeRefTable.Record rec = new TypeRefTable.Record(); - rec.ResolutionScope = resolutionScope; - rec.TypeName = this.Strings.Add(name); - rec.TypeNameSpace = ns == null ? 0 : this.Strings.Add(ns); - return 0x01000000 | this.TypeRef.AddRecord(rec); - } - - public void __Save(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - SaveImpl(null, portableExecutableKind, imageFileMachine); - } - - public void __Save(Stream stream, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek || stream.Position != 0) - { - throw new ArgumentException("Stream must support read/write/seek and current position must be zero.", "stream"); - } - SaveImpl(stream, portableExecutableKind, imageFileMachine); - } - - private void SaveImpl(Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) - { - SetIsSaved(); - PopulatePropertyAndEventTables(); - IList attributes = asm.GetCustomAttributesData(null); - if (attributes.Count > 0) - { - int mscorlib = ImportAssemblyRef(universe.Mscorlib); - int[] placeholderTokens = new int[4]; - string[] placeholderTypeNames = new string[] { "AssemblyAttributesGoHere", "AssemblyAttributesGoHereM", "AssemblyAttributesGoHereS", "AssemblyAttributesGoHereSM" }; - foreach (CustomAttributeData cad in attributes) - { - int index; - if (cad.Constructor.DeclaringType.BaseType == universe.System_Security_Permissions_CodeAccessSecurityAttribute) - { - if (cad.Constructor.DeclaringType.IsAllowMultipleCustomAttribute) - { - index = 3; - } - else - { - index = 2; - } - } - else if (cad.Constructor.DeclaringType.IsAllowMultipleCustomAttribute) - { - index = 1; - } - else - { - index = 0; - } - if (placeholderTokens[index] == 0) - { - // we manually add a TypeRef without looking it up in mscorlib, because Mono and Silverlight's mscorlib don't have these types - placeholderTokens[index] = AddTypeRefByName(mscorlib, "System.Runtime.CompilerServices", placeholderTypeNames[index]); - } - SetCustomAttribute(placeholderTokens[index], cad.__ToBuilder()); - } - } - FillAssemblyRefTable(); - EmitResources(); - ModuleWriter.WriteModule(null, null, this, PEFileKinds.Dll, portableExecutableKind, imageFileMachine, unmanagedResources, 0, streamOrNull); - } - - public void __AddAssemblyReference(AssemblyName assemblyName) - { - __AddAssemblyReference(assemblyName, null); - } - - public void __AddAssemblyReference(AssemblyName assemblyName, Assembly assembly) - { - if (referencedAssemblyNames == null) - { - referencedAssemblyNames = new List(); - } - referencedAssemblyNames.Add((AssemblyName)assemblyName.Clone()); - int token = FindOrAddAssemblyRef(assemblyName, true); - if (assembly != null) - { - referencedAssemblies.Add(assembly, token); - } - } - - public override AssemblyName[] __GetReferencedAssemblies() - { - List list = new List(); - if (referencedAssemblyNames != null) - { - foreach (AssemblyName name in referencedAssemblyNames) - { - if (!list.Contains(name)) - { - list.Add(name); - } - } - } - foreach (Assembly asm in referencedAssemblies.Keys) - { - AssemblyName name = asm.GetName(); - if (!list.Contains(name)) - { - list.Add(name); - } - } - return list.ToArray(); - } - - public void __AddModuleReference(string module) - { - this.ModuleRef.FindOrAddRecord(module == null ? 0 : this.Strings.Add(module)); - } - - public override string[] __GetReferencedModules() - { - string[] arr = new string[this.ModuleRef.RowCount]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = this.Strings.Find(this.ModuleRef.records[i]); - } - return arr; - } - - public override Type[] __GetReferencedTypes() - { - List list = new List(); - foreach (KeyValuePair kv in typeTokens) - { - if (kv.Value >> 24 == TypeRefTable.Index) - { - list.Add(kv.Key); - } - } - return list.ToArray(); - } - - public override Type[] __GetExportedTypes() - { - throw new NotImplementedException(); - } - - public int __AddModule(int flags, string name, byte[] hash) - { - FileTable.Record file = new FileTable.Record(); - file.Flags = flags; - file.Name = this.Strings.Add(name); - file.HashValue = this.Blobs.Add(ByteBuffer.Wrap(hash)); - return 0x26000000 + this.File.AddRecord(file); - } - - public int __AddManifestResource(int offset, ResourceAttributes flags, string name, int implementation) - { - ManifestResourceTable.Record res = new ManifestResourceTable.Record(); - res.Offset = offset; - res.Flags = (int)flags; - res.Name = this.Strings.Add(name); - res.Implementation = implementation; - return 0x28000000 + this.ManifestResource.AddRecord(res); - } - - public void __SetCustomAttributeFor(int token, CustomAttributeBuilder customBuilder) - { - SetCustomAttribute(token, customBuilder); - } - - public RelativeVirtualAddress __AddVTableFixups(MethodBuilder[] methods, int type) - { - initializedData.Align(8); - VTableFixups fixups; - fixups.initializedDataOffset = (uint)initializedData.Position; - fixups.count = (ushort)methods.Length; - fixups.type = (ushort)type; - foreach (MethodBuilder mb in methods) - { - initializedData.Write(mb.MetadataToken); - if (fixups.SlotWidth == 8) - { - initializedData.Write(0); - } - } - vtablefixups.Add(fixups); - return new RelativeVirtualAddress(fixups.initializedDataOffset); - } - - public void __AddUnmanagedExportStub(string name, int ordinal, RelativeVirtualAddress rva) - { - AddUnmanagedExport(name, ordinal, null, rva); - } - - internal void AddUnmanagedExport(string name, int ordinal, MethodBuilder methodBuilder, RelativeVirtualAddress rva) - { - UnmanagedExport export; - export.name = name; - export.ordinal = ordinal; - export.mb = methodBuilder; - export.rva = rva; - unmanagedExports.Add(export); - } - - internal void SetInterfaceImplementationCustomAttribute(TypeBuilder typeBuilder, Type interfaceType, CustomAttributeBuilder cab) - { - // NOTE since interfaceimpls are extremely common and custom attributes on them are extremely rare, - // we store (and resolve) the custom attributes in such away as to avoid impacting the common case performance - if (interfaceImplCustomAttributes == null) - { - interfaceImplCustomAttributes = new List(); - } - InterfaceImplCustomAttribute rec; - rec.type = typeBuilder.MetadataToken; - int token = GetTypeToken(interfaceType).Token; - switch (token >> 24) - { - case TypeDefTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case TypeRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case TypeSpecTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - default: - throw new InvalidOperationException(); - } - rec.interfaceType = token; - rec.pseudoToken = AllocPseudoToken(); - interfaceImplCustomAttributes.Add(rec); - SetCustomAttribute(rec.pseudoToken, cab); - } - - internal void ResolveInterfaceImplPseudoTokens() - { - if (interfaceImplCustomAttributes != null) - { - foreach (InterfaceImplCustomAttribute rec in interfaceImplCustomAttributes) - { - for (int i = 0; i < InterfaceImpl.records.Length; i++) - { - if (InterfaceImpl.records[i].Class == rec.type && InterfaceImpl.records[i].Interface == rec.interfaceType) - { - RegisterTokenFixup(rec.pseudoToken, (InterfaceImplTable.Index << 24) | (i + 1)); - break; - } - } - } - } - } - - internal void FixupPseudoToken(ref int token) - { - if (IsPseudoToken(token)) - { - token = ResolvePseudoToken(token); - } - } - - internal void SetIsSaved() - { - if (saved) - { - throw new InvalidOperationException(); - } - saved = true; - } - - internal bool IsSaved - { - get { return saved; } - } - - internal override string GetString(int index) - { - return this.Strings.Find(index); - } - } - - struct UnmanagedExport - { - internal string name; - internal int ordinal; - internal RelativeVirtualAddress rva; - internal MethodBuilder mb; - } - - public struct RelativeVirtualAddress - { - internal readonly uint initializedDataOffset; - - internal RelativeVirtualAddress(uint initializedDataOffset) - { - this.initializedDataOffset = initializedDataOffset; - } - - public static RelativeVirtualAddress operator +(RelativeVirtualAddress rva, int offset) - { - return new RelativeVirtualAddress(rva.initializedDataOffset + (uint)offset); - } - } - - class ArrayMethod : MethodInfo - { - private readonly Module module; - private readonly Type arrayClass; - private readonly string methodName; - private readonly CallingConventions callingConvention; - private readonly Type returnType; - protected readonly Type[] parameterTypes; - private MethodSignature methodSignature; - - internal ArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - { - this.module = module; - this.arrayClass = arrayClass; - this.methodName = methodName; - this.callingConvention = callingConvention; - this.returnType = returnType ?? module.universe.System_Void; - this.parameterTypes = Util.Copy(parameterTypes); - } - - public override MethodBody GetMethodBody() - { - throw new InvalidOperationException(); - } - - public override int __MethodRVA - { - get { throw new InvalidOperationException(); } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - throw new NotSupportedException(); - } - - public override ParameterInfo[] GetParameters() - { - throw new NotSupportedException(); - } - - internal override int ImportTo(ModuleBuilder module) - { - return module.ImportMethodOrField(arrayClass, methodName, MethodSignature); - } - - public override MethodAttributes Attributes - { - get { throw new NotSupportedException(); } - } - - public override CallingConventions CallingConvention - { - get { return callingConvention; } - } - - public override Type DeclaringType - { - get { return arrayClass; } - } - - internal override MethodSignature MethodSignature - { - get - { - if (methodSignature == null) - { - methodSignature = MethodSignature.MakeFromBuilder(returnType, parameterTypes, new PackedCustomModifiers(), callingConvention, 0); - } - return methodSignature; - } - } - - public override Module Module - { - // FXBUG like .NET, we return the module that GetArrayMethod was called on, not the module associated with the array type - get { return module; } - } - - public override string Name - { - get { return methodName; } - } - - internal override int ParameterCount - { - get { return parameterTypes.Length; } - } - - public override ParameterInfo ReturnParameter - { - // FXBUG like .NET, we throw NotImplementedException - get { throw new NotImplementedException(); } - } - - public override Type ReturnType - { - get { return returnType; } - } - - internal override bool HasThis - { - get { return (callingConvention & (CallingConventions.HasThis | CallingConventions.ExplicitThis)) == CallingConventions.HasThis; } - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - - internal override bool IsBaked - { - get { return arrayClass.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/OpCode.cs b/mcs/class/IKVM.Reflection/Emit/OpCode.cs deleted file mode 100644 index 1d75a0a433a..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/OpCode.cs +++ /dev/null @@ -1,288 +0,0 @@ -/* - Copyright (C) 2008, 2010 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Diagnostics; - -namespace IKVM.Reflection.Emit -{ - public struct OpCode - { - private const int ValueCount = 1024; - private const int OperandTypeCount = 19; - private const int FlowControlCount = 9; - private const int StackDiffCount = 5; - private const int OpCodeTypeCount = 6; - private const int StackBehaviourPopCount = 20; - private const int StackBehaviourPushCount = 9; - private static readonly StackBehaviour[] pop = { - StackBehaviour.Pop0, - StackBehaviour.Pop1, - StackBehaviour.Pop1_pop1, - StackBehaviour.Popi, - StackBehaviour.Popi_pop1, - StackBehaviour.Popi_popi, - StackBehaviour.Popi_popi8, - StackBehaviour.Popi_popi_popi, - StackBehaviour.Popi_popr4, - StackBehaviour.Popi_popr8, - StackBehaviour.Popref, - StackBehaviour.Popref_pop1, - StackBehaviour.Popref_popi, - StackBehaviour.Popref_popi_popi, - StackBehaviour.Popref_popi_popi8, - StackBehaviour.Popref_popi_popr4, - StackBehaviour.Popref_popi_popr8, - StackBehaviour.Popref_popi_popref, - StackBehaviour.Varpop, - StackBehaviour.Popref_popi_pop1 - }; - private static readonly StackBehaviour[] push = { - StackBehaviour.Push0, - StackBehaviour.Push1, - StackBehaviour.Push1_push1, - StackBehaviour.Pushi, - StackBehaviour.Pushi8, - StackBehaviour.Pushr4, - StackBehaviour.Pushr8, - StackBehaviour.Pushref, - StackBehaviour.Varpush - }; - private readonly int value; - - internal OpCode(int value) - { - this.value = value; - } - - public override bool Equals(object obj) - { - return this == obj as OpCode?; - } - - public override int GetHashCode() - { - return value; - } - - public bool Equals(OpCode other) - { - return this == other; - } - - public static bool operator ==(OpCode a, OpCode b) - { - return a.value == b.value; - } - - public static bool operator !=(OpCode a, OpCode b) - { - return !(a == b); - } - - public short Value - { - get { return (short)(value >> 22); } - } - - public int Size - { - get { return value < 0 ? 2 : 1; } - } - -#if !GENERATOR - public string Name - { - get { return OpCodes.GetName(this.Value); } - } -#endif - - public OperandType OperandType - { - get { return (OperandType)((value & 0x3FFFFF) % OperandTypeCount); } - } - - public FlowControl FlowControl - { - get { return (FlowControl)(((value & 0x3FFFFF) / OperandTypeCount) % FlowControlCount); } - } - - internal int StackDiff - { - get { return ((((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount)) % StackDiffCount) - 3); } - } - - public OpCodeType OpCodeType - { - get { return (OpCodeType)(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount)) % OpCodeTypeCount); } - } - - public StackBehaviour StackBehaviourPop - { - get { return pop[(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount * OpCodeTypeCount)) % StackBehaviourPopCount)]; } - } - - public StackBehaviour StackBehaviourPush - { - get { return push[(((value & 0x3FFFFF) / (OperandTypeCount * FlowControlCount * StackDiffCount * OpCodeTypeCount * StackBehaviourPopCount)) % StackBehaviourPushCount)]; } - } - -#if GENERATOR - static void Main(string[] args) - { - Debug.Assert(pop.Length == StackBehaviourPopCount); - Debug.Assert(push.Length == StackBehaviourPushCount); - CheckEnumRange(typeof(FlowControl), FlowControlCount); - CheckEnumRange(typeof(OpCodeType), OpCodeTypeCount); - CheckEnumRange(typeof(OperandType), OperandTypeCount); - foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) - { - System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null); - IKVM.Reflection.Emit.OpCode opc2 = new IKVM.Reflection.Emit.OpCode(Pack(opc1)); - Debug.Assert(opc1.Value == opc2.Value); - Debug.Assert(opc1.Size == opc2.Size); - Debug.Assert((int)opc1.FlowControl == (int)opc2.FlowControl); - Debug.Assert((int)opc1.OpCodeType == (int)opc2.OpCodeType); - Debug.Assert((int)opc1.OperandType == (int)opc2.OperandType); - Debug.Assert((int)opc1.StackBehaviourPop == (int)opc2.StackBehaviourPop); - Debug.Assert((int)opc1.StackBehaviourPush == (int)opc2.StackBehaviourPush); - Console.WriteLine("\t\tpublic static readonly OpCode {0} = new OpCode({1});", field.Name, Pack(opc1)); - } - Console.WriteLine(); - Console.WriteLine("\t\tinternal static string GetName(int value)"); - Console.WriteLine("\t\t{"); - Console.WriteLine("\t\t\tswitch (value)"); - Console.WriteLine("\t\t\t{"); - foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) - { - System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null); - Console.WriteLine("\t\t\t\tcase {0}:", opc1.Value); - Console.WriteLine("\t\t\t\t\treturn \"{0}\";", opc1.Name); - } - Console.WriteLine("\t\t\t}"); - Console.WriteLine("\t\t\tthrow new ArgumentOutOfRangeException();"); - Console.WriteLine("\t\t}"); - Console.WriteLine(); - Console.WriteLine("\t\tpublic static bool TakesSingleByteArgument(OpCode inst)"); - Console.WriteLine("\t\t{"); - Console.WriteLine("\t\t\tswitch (inst.Value)"); - Console.WriteLine("\t\t\t{"); - foreach (var field in typeof(System.Reflection.Emit.OpCodes).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) - { - System.Reflection.Emit.OpCode opc1 = (System.Reflection.Emit.OpCode)field.GetValue(null); - if (System.Reflection.Emit.OpCodes.TakesSingleByteArgument(opc1)) - { - Console.WriteLine("\t\t\t\tcase {0}:", opc1.Value); - } - } - Console.WriteLine("\t\t\t\t\treturn true;"); - Console.WriteLine("\t\t\t\tdefault:"); - Console.WriteLine("\t\t\t\t\treturn false;"); - Console.WriteLine("\t\t\t}"); - Console.WriteLine("\t\t}"); - } - - private static void CheckEnumRange(System.Type type, int count) - { - foreach (var field in type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)) - { - int value = (int)field.GetValue(null); - Debug.Assert(value >= 0 && value < count); - } - } - - static int Pack(System.Reflection.Emit.OpCode opcode) - { - int value = 0; - value *= StackBehaviourPushCount; - value += Map(push, opcode.StackBehaviourPush); - value *= StackBehaviourPopCount; - value += Map(pop, opcode.StackBehaviourPop); - value *= OpCodeTypeCount; - value += (int)opcode.OpCodeType; - value *= StackDiffCount; - value += 3 + GetStackDiff(opcode.StackBehaviourPush) + GetStackDiff(opcode.StackBehaviourPop); - value *= FlowControlCount; - value += (int)opcode.FlowControl; - value *= OperandTypeCount; - value += (int)opcode.OperandType; - return (opcode.Value << 22) | value; - } - - private static int Map(StackBehaviour[] array, System.Reflection.Emit.StackBehaviour stackBehaviour) - { - for (int i = 0; i < array.Length; i++) - { - if ((int)array[i] == (int)stackBehaviour) - { - return i; - } - } - throw new InvalidOperationException(); - } - - static int GetStackDiff(System.Reflection.Emit.StackBehaviour sb) - { - switch (sb) - { - case System.Reflection.Emit.StackBehaviour.Pop0: - case System.Reflection.Emit.StackBehaviour.Push0: - case System.Reflection.Emit.StackBehaviour.Varpop: - case System.Reflection.Emit.StackBehaviour.Varpush: - return 0; - case System.Reflection.Emit.StackBehaviour.Pop1: - case System.Reflection.Emit.StackBehaviour.Popi: - case System.Reflection.Emit.StackBehaviour.Popref: - return -1; - case System.Reflection.Emit.StackBehaviour.Pop1_pop1: - case System.Reflection.Emit.StackBehaviour.Popi_pop1: - case System.Reflection.Emit.StackBehaviour.Popi_popi: - case System.Reflection.Emit.StackBehaviour.Popi_popi8: - case System.Reflection.Emit.StackBehaviour.Popi_popr4: - case System.Reflection.Emit.StackBehaviour.Popi_popr8: - case System.Reflection.Emit.StackBehaviour.Popref_pop1: - case System.Reflection.Emit.StackBehaviour.Popref_popi: - return -2; - case System.Reflection.Emit.StackBehaviour.Popi_popi_popi: - case System.Reflection.Emit.StackBehaviour.Popref_popi_pop1: - case System.Reflection.Emit.StackBehaviour.Popref_popi_popi: - case System.Reflection.Emit.StackBehaviour.Popref_popi_popi8: - case System.Reflection.Emit.StackBehaviour.Popref_popi_popr4: - case System.Reflection.Emit.StackBehaviour.Popref_popi_popr8: - case System.Reflection.Emit.StackBehaviour.Popref_popi_popref: - return -3; - case System.Reflection.Emit.StackBehaviour.Push1: - case System.Reflection.Emit.StackBehaviour.Pushi: - case System.Reflection.Emit.StackBehaviour.Pushi8: - case System.Reflection.Emit.StackBehaviour.Pushr4: - case System.Reflection.Emit.StackBehaviour.Pushr8: - case System.Reflection.Emit.StackBehaviour.Pushref: - return 1; - case System.Reflection.Emit.StackBehaviour.Push1_push1: - return 2; - } - throw new InvalidOperationException(); - } -#endif // GENERATOR - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/OpCodes.cs b/mcs/class/IKVM.Reflection/Emit/OpCodes.cs deleted file mode 100644 index bb2ddd84a48..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/OpCodes.cs +++ /dev/null @@ -1,749 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection.Emit -{ - public sealed class OpCodes - { - public static readonly OpCode Nop = new OpCode(4888); - public static readonly OpCode Break = new OpCode(4199116); - public static readonly OpCode Ldarg_0 = new OpCode(8492847); - public static readonly OpCode Ldarg_1 = new OpCode(12687151); - public static readonly OpCode Ldarg_2 = new OpCode(16881455); - public static readonly OpCode Ldarg_3 = new OpCode(21075759); - public static readonly OpCode Ldloc_0 = new OpCode(25270063); - public static readonly OpCode Ldloc_1 = new OpCode(29464367); - public static readonly OpCode Ldloc_2 = new OpCode(33658671); - public static readonly OpCode Ldloc_3 = new OpCode(37852975); - public static readonly OpCode Stloc_0 = new OpCode(41949467); - public static readonly OpCode Stloc_1 = new OpCode(46143771); - public static readonly OpCode Stloc_2 = new OpCode(50338075); - public static readonly OpCode Stloc_3 = new OpCode(54532379); - public static readonly OpCode Ldarg_S = new OpCode(58824508); - public static readonly OpCode Ldarga_S = new OpCode(63224012); - public static readonly OpCode Starg_S = new OpCode(67115304); - public static readonly OpCode Ldloc_S = new OpCode(71407420); - public static readonly OpCode Ldloca_S = new OpCode(75806924); - public static readonly OpCode Stloc_S = new OpCode(79698216); - public static readonly OpCode Ldnull = new OpCode(84609339); - public static readonly OpCode Ldc_I4_M1 = new OpCode(88389823); - public static readonly OpCode Ldc_I4_0 = new OpCode(92584127); - public static readonly OpCode Ldc_I4_1 = new OpCode(96778431); - public static readonly OpCode Ldc_I4_2 = new OpCode(100972735); - public static readonly OpCode Ldc_I4_3 = new OpCode(105167039); - public static readonly OpCode Ldc_I4_4 = new OpCode(109361343); - public static readonly OpCode Ldc_I4_5 = new OpCode(113555647); - public static readonly OpCode Ldc_I4_6 = new OpCode(117749951); - public static readonly OpCode Ldc_I4_7 = new OpCode(121944255); - public static readonly OpCode Ldc_I4_8 = new OpCode(126138559); - public static readonly OpCode Ldc_I4_S = new OpCode(130332874); - public static readonly OpCode Ldc_I4 = new OpCode(134530584); - public static readonly OpCode Ldc_I8 = new OpCode(138827489); - public static readonly OpCode Ldc_R4 = new OpCode(143124407); - public static readonly OpCode Ldc_R8 = new OpCode(147421301); - public static readonly OpCode Dup = new OpCode(155404637); - public static readonly OpCode Pop = new OpCode(159393399); - public static readonly OpCode Jmp = new OpCode(163582686); - public static readonly OpCode Call = new OpCode(168690130); - public static readonly OpCode Calli = new OpCode(172884439); - public static readonly OpCode Ret = new OpCode(176258034); - public static readonly OpCode Br_S = new OpCode(180356455); - public static readonly OpCode Brfalse_S = new OpCode(184566035); - public static readonly OpCode Brtrue_S = new OpCode(188760339); - public static readonly OpCode Beq_S = new OpCode(192949342); - public static readonly OpCode Bge_S = new OpCode(197143646); - public static readonly OpCode Bgt_S = new OpCode(201337950); - public static readonly OpCode Ble_S = new OpCode(205532254); - public static readonly OpCode Blt_S = new OpCode(209726558); - public static readonly OpCode Bne_Un_S = new OpCode(213920862); - public static readonly OpCode Bge_Un_S = new OpCode(218115166); - public static readonly OpCode Bgt_Un_S = new OpCode(222309470); - public static readonly OpCode Ble_Un_S = new OpCode(226503774); - public static readonly OpCode Blt_Un_S = new OpCode(230698078); - public static readonly OpCode Br = new OpCode(234885812); - public static readonly OpCode Brfalse = new OpCode(239095392); - public static readonly OpCode Brtrue = new OpCode(243289696); - public static readonly OpCode Beq = new OpCode(247475279); - public static readonly OpCode Bge = new OpCode(251669583); - public static readonly OpCode Bgt = new OpCode(255863887); - public static readonly OpCode Ble = new OpCode(260058191); - public static readonly OpCode Blt = new OpCode(264252495); - public static readonly OpCode Bne_Un = new OpCode(268446799); - public static readonly OpCode Bge_Un = new OpCode(272641103); - public static readonly OpCode Bgt_Un = new OpCode(276835407); - public static readonly OpCode Ble_Un = new OpCode(281029711); - public static readonly OpCode Blt_Un = new OpCode(285224015); - public static readonly OpCode Switch = new OpCode(289427051); - public static readonly OpCode Ldind_I1 = new OpCode(293929358); - public static readonly OpCode Ldind_U1 = new OpCode(298123662); - public static readonly OpCode Ldind_I2 = new OpCode(302317966); - public static readonly OpCode Ldind_U2 = new OpCode(306512270); - public static readonly OpCode Ldind_I4 = new OpCode(310706574); - public static readonly OpCode Ldind_U4 = new OpCode(314900878); - public static readonly OpCode Ldind_I8 = new OpCode(319197782); - public static readonly OpCode Ldind_I = new OpCode(323289486); - public static readonly OpCode Ldind_R4 = new OpCode(327688990); - public static readonly OpCode Ldind_R8 = new OpCode(331985894); - public static readonly OpCode Ldind_Ref = new OpCode(336282798); - public static readonly OpCode Stind_Ref = new OpCode(339768820); - public static readonly OpCode Stind_I1 = new OpCode(343963124); - public static readonly OpCode Stind_I2 = new OpCode(348157428); - public static readonly OpCode Stind_I4 = new OpCode(352351732); - public static readonly OpCode Stind_I8 = new OpCode(356551166); - public static readonly OpCode Stind_R4 = new OpCode(360755730); - public static readonly OpCode Stind_R8 = new OpCode(364955164); - public static readonly OpCode Add = new OpCode(369216329); - public static readonly OpCode Sub = new OpCode(373410633); - public static readonly OpCode Mul = new OpCode(377604937); - public static readonly OpCode Div = new OpCode(381799241); - public static readonly OpCode Div_Un = new OpCode(385993545); - public static readonly OpCode Rem = new OpCode(390187849); - public static readonly OpCode Rem_Un = new OpCode(394382153); - public static readonly OpCode And = new OpCode(398576457); - public static readonly OpCode Or = new OpCode(402770761); - public static readonly OpCode Xor = new OpCode(406965065); - public static readonly OpCode Shl = new OpCode(411159369); - public static readonly OpCode Shr = new OpCode(415353673); - public static readonly OpCode Shr_Un = new OpCode(419547977); - public static readonly OpCode Neg = new OpCode(423737322); - public static readonly OpCode Not = new OpCode(427931626); - public static readonly OpCode Conv_I1 = new OpCode(432331130); - public static readonly OpCode Conv_I2 = new OpCode(436525434); - public static readonly OpCode Conv_I4 = new OpCode(440719738); - public static readonly OpCode Conv_I8 = new OpCode(445016642); - public static readonly OpCode Conv_R4 = new OpCode(449313546); - public static readonly OpCode Conv_R8 = new OpCode(453610450); - public static readonly OpCode Conv_U4 = new OpCode(457496954); - public static readonly OpCode Conv_U8 = new OpCode(461793858); - public static readonly OpCode Callvirt = new OpCode(466484004); - public static readonly OpCode Cpobj = new OpCode(469790542); - public static readonly OpCode Ldobj = new OpCode(474077528); - public static readonly OpCode Ldstr = new OpCode(478872210); - public static readonly OpCode Newobj = new OpCode(483158791); - public static readonly OpCode Castclass = new OpCode(487311950); - public static readonly OpCode Isinst = new OpCode(491095854); - public static readonly OpCode Conv_R_Un = new OpCode(495553490); - public static readonly OpCode Unbox = new OpCode(507874780); - public static readonly OpCode Throw = new OpCode(511759452); - public static readonly OpCode Ldfld = new OpCode(516056466); - public static readonly OpCode Ldflda = new OpCode(520455970); - public static readonly OpCode Stfld = new OpCode(524347262); - public static readonly OpCode Ldsfld = new OpCode(528588249); - public static readonly OpCode Ldsflda = new OpCode(532987753); - public static readonly OpCode Stsfld = new OpCode(536879045); - public static readonly OpCode Stobj = new OpCode(541090290); - public static readonly OpCode Conv_Ovf_I1_Un = new OpCode(545577338); - public static readonly OpCode Conv_Ovf_I2_Un = new OpCode(549771642); - public static readonly OpCode Conv_Ovf_I4_Un = new OpCode(553965946); - public static readonly OpCode Conv_Ovf_I8_Un = new OpCode(558262850); - public static readonly OpCode Conv_Ovf_U1_Un = new OpCode(562354554); - public static readonly OpCode Conv_Ovf_U2_Un = new OpCode(566548858); - public static readonly OpCode Conv_Ovf_U4_Un = new OpCode(570743162); - public static readonly OpCode Conv_Ovf_U8_Un = new OpCode(575040066); - public static readonly OpCode Conv_Ovf_I_Un = new OpCode(579131770); - public static readonly OpCode Conv_Ovf_U_Un = new OpCode(583326074); - public static readonly OpCode Box = new OpCode(587930786); - public static readonly OpCode Newarr = new OpCode(592133640); - public static readonly OpCode Ldlen = new OpCode(595953446); - public static readonly OpCode Ldelema = new OpCode(600157847); - public static readonly OpCode Ldelem_I1 = new OpCode(604352143); - public static readonly OpCode Ldelem_U1 = new OpCode(608546447); - public static readonly OpCode Ldelem_I2 = new OpCode(612740751); - public static readonly OpCode Ldelem_U2 = new OpCode(616935055); - public static readonly OpCode Ldelem_I4 = new OpCode(621129359); - public static readonly OpCode Ldelem_U4 = new OpCode(625323663); - public static readonly OpCode Ldelem_I8 = new OpCode(629620567); - public static readonly OpCode Ldelem_I = new OpCode(633712271); - public static readonly OpCode Ldelem_R4 = new OpCode(638111775); - public static readonly OpCode Ldelem_R8 = new OpCode(642408679); - public static readonly OpCode Ldelem_Ref = new OpCode(646705583); - public static readonly OpCode Stelem_I = new OpCode(650186475); - public static readonly OpCode Stelem_I1 = new OpCode(654380779); - public static readonly OpCode Stelem_I2 = new OpCode(658575083); - public static readonly OpCode Stelem_I4 = new OpCode(662769387); - public static readonly OpCode Stelem_I8 = new OpCode(666968821); - public static readonly OpCode Stelem_R4 = new OpCode(671168255); - public static readonly OpCode Stelem_R8 = new OpCode(675367689); - public static readonly OpCode Stelem_Ref = new OpCode(679567123); - public static readonly OpCode Ldelem = new OpCode(683838727); - public static readonly OpCode Stelem = new OpCode(687965999); - public static readonly OpCode Unbox_Any = new OpCode(692217246); - public static readonly OpCode Conv_Ovf_I1 = new OpCode(751098234); - public static readonly OpCode Conv_Ovf_U1 = new OpCode(755292538); - public static readonly OpCode Conv_Ovf_I2 = new OpCode(759486842); - public static readonly OpCode Conv_Ovf_U2 = new OpCode(763681146); - public static readonly OpCode Conv_Ovf_I4 = new OpCode(767875450); - public static readonly OpCode Conv_Ovf_U4 = new OpCode(772069754); - public static readonly OpCode Conv_Ovf_I8 = new OpCode(776366658); - public static readonly OpCode Conv_Ovf_U8 = new OpCode(780560962); - public static readonly OpCode Refanyval = new OpCode(814012802); - public static readonly OpCode Ckfinite = new OpCode(818514898); - public static readonly OpCode Mkrefany = new OpCode(830595078); - public static readonly OpCode Ldtoken = new OpCode(872728098); - public static readonly OpCode Conv_U2 = new OpCode(876927354); - public static readonly OpCode Conv_U1 = new OpCode(881121658); - public static readonly OpCode Conv_I = new OpCode(885315962); - public static readonly OpCode Conv_Ovf_I = new OpCode(889510266); - public static readonly OpCode Conv_Ovf_U = new OpCode(893704570); - public static readonly OpCode Add_Ovf = new OpCode(897698633); - public static readonly OpCode Add_Ovf_Un = new OpCode(901892937); - public static readonly OpCode Mul_Ovf = new OpCode(906087241); - public static readonly OpCode Mul_Ovf_Un = new OpCode(910281545); - public static readonly OpCode Sub_Ovf = new OpCode(914475849); - public static readonly OpCode Sub_Ovf_Un = new OpCode(918670153); - public static readonly OpCode Endfinally = new OpCode(922751806); - public static readonly OpCode Leave = new OpCode(926945972); - public static readonly OpCode Leave_S = new OpCode(931140291); - public static readonly OpCode Stind_I = new OpCode(935359988); - public static readonly OpCode Conv_U = new OpCode(939841914); - public static readonly OpCode Prefix7 = new OpCode(1040189696); - public static readonly OpCode Prefix6 = new OpCode(1044384000); - public static readonly OpCode Prefix5 = new OpCode(1048578304); - public static readonly OpCode Prefix4 = new OpCode(1052772608); - public static readonly OpCode Prefix3 = new OpCode(1056966912); - public static readonly OpCode Prefix2 = new OpCode(1061161216); - public static readonly OpCode Prefix1 = new OpCode(1065355520); - public static readonly OpCode Prefixref = new OpCode(1069549824); - public static readonly OpCode Arglist = new OpCode(-2147170789); - public static readonly OpCode Ceq = new OpCode(-2142966567); - public static readonly OpCode Cgt = new OpCode(-2138772263); - public static readonly OpCode Cgt_Un = new OpCode(-2134577959); - public static readonly OpCode Clt = new OpCode(-2130383655); - public static readonly OpCode Clt_Un = new OpCode(-2126189351); - public static readonly OpCode Ldftn = new OpCode(-2122004966); - public static readonly OpCode Ldvirtftn = new OpCode(-2117759533); - public static readonly OpCode Ldarg = new OpCode(-2109627244); - public static readonly OpCode Ldarga = new OpCode(-2105227740); - public static readonly OpCode Starg = new OpCode(-2101336448); - public static readonly OpCode Ldloc = new OpCode(-2097044332); - public static readonly OpCode Ldloca = new OpCode(-2092644828); - public static readonly OpCode Stloc = new OpCode(-2088753536); - public static readonly OpCode Localloc = new OpCode(-2084241010); - public static readonly OpCode Endfilter = new OpCode(-2076160335); - public static readonly OpCode Unaligned = new OpCode(-2071982151); - public static readonly OpCode Volatile = new OpCode(-2067787858); - public static readonly OpCode Tailcall = new OpCode(-2063593554); - public static readonly OpCode Initobj = new OpCode(-2059384859); - public static readonly OpCode Constrained = new OpCode(-2055204938); - public static readonly OpCode Cpblk = new OpCode(-2050974371); - public static readonly OpCode Initblk = new OpCode(-2046780067); - public static readonly OpCode Rethrow = new OpCode(-2038428509); - public static readonly OpCode Sizeof = new OpCode(-2029730269); - public static readonly OpCode Refanytype = new OpCode(-2025531014); - public static readonly OpCode Readonly = new OpCode(-2021650514); - - internal static string GetName(int value) - { - switch (value) - { - case 0: - return "nop"; - case 1: - return "break"; - case 2: - return "ldarg.0"; - case 3: - return "ldarg.1"; - case 4: - return "ldarg.2"; - case 5: - return "ldarg.3"; - case 6: - return "ldloc.0"; - case 7: - return "ldloc.1"; - case 8: - return "ldloc.2"; - case 9: - return "ldloc.3"; - case 10: - return "stloc.0"; - case 11: - return "stloc.1"; - case 12: - return "stloc.2"; - case 13: - return "stloc.3"; - case 14: - return "ldarg.s"; - case 15: - return "ldarga.s"; - case 16: - return "starg.s"; - case 17: - return "ldloc.s"; - case 18: - return "ldloca.s"; - case 19: - return "stloc.s"; - case 20: - return "ldnull"; - case 21: - return "ldc.i4.m1"; - case 22: - return "ldc.i4.0"; - case 23: - return "ldc.i4.1"; - case 24: - return "ldc.i4.2"; - case 25: - return "ldc.i4.3"; - case 26: - return "ldc.i4.4"; - case 27: - return "ldc.i4.5"; - case 28: - return "ldc.i4.6"; - case 29: - return "ldc.i4.7"; - case 30: - return "ldc.i4.8"; - case 31: - return "ldc.i4.s"; - case 32: - return "ldc.i4"; - case 33: - return "ldc.i8"; - case 34: - return "ldc.r4"; - case 35: - return "ldc.r8"; - case 37: - return "dup"; - case 38: - return "pop"; - case 39: - return "jmp"; - case 40: - return "call"; - case 41: - return "calli"; - case 42: - return "ret"; - case 43: - return "br.s"; - case 44: - return "brfalse.s"; - case 45: - return "brtrue.s"; - case 46: - return "beq.s"; - case 47: - return "bge.s"; - case 48: - return "bgt.s"; - case 49: - return "ble.s"; - case 50: - return "blt.s"; - case 51: - return "bne.un.s"; - case 52: - return "bge.un.s"; - case 53: - return "bgt.un.s"; - case 54: - return "ble.un.s"; - case 55: - return "blt.un.s"; - case 56: - return "br"; - case 57: - return "brfalse"; - case 58: - return "brtrue"; - case 59: - return "beq"; - case 60: - return "bge"; - case 61: - return "bgt"; - case 62: - return "ble"; - case 63: - return "blt"; - case 64: - return "bne.un"; - case 65: - return "bge.un"; - case 66: - return "bgt.un"; - case 67: - return "ble.un"; - case 68: - return "blt.un"; - case 69: - return "switch"; - case 70: - return "ldind.i1"; - case 71: - return "ldind.u1"; - case 72: - return "ldind.i2"; - case 73: - return "ldind.u2"; - case 74: - return "ldind.i4"; - case 75: - return "ldind.u4"; - case 76: - return "ldind.i8"; - case 77: - return "ldind.i"; - case 78: - return "ldind.r4"; - case 79: - return "ldind.r8"; - case 80: - return "ldind.ref"; - case 81: - return "stind.ref"; - case 82: - return "stind.i1"; - case 83: - return "stind.i2"; - case 84: - return "stind.i4"; - case 85: - return "stind.i8"; - case 86: - return "stind.r4"; - case 87: - return "stind.r8"; - case 88: - return "add"; - case 89: - return "sub"; - case 90: - return "mul"; - case 91: - return "div"; - case 92: - return "div.un"; - case 93: - return "rem"; - case 94: - return "rem.un"; - case 95: - return "and"; - case 96: - return "or"; - case 97: - return "xor"; - case 98: - return "shl"; - case 99: - return "shr"; - case 100: - return "shr.un"; - case 101: - return "neg"; - case 102: - return "not"; - case 103: - return "conv.i1"; - case 104: - return "conv.i2"; - case 105: - return "conv.i4"; - case 106: - return "conv.i8"; - case 107: - return "conv.r4"; - case 108: - return "conv.r8"; - case 109: - return "conv.u4"; - case 110: - return "conv.u8"; - case 111: - return "callvirt"; - case 112: - return "cpobj"; - case 113: - return "ldobj"; - case 114: - return "ldstr"; - case 115: - return "newobj"; - case 116: - return "castclass"; - case 117: - return "isinst"; - case 118: - return "conv.r.un"; - case 121: - return "unbox"; - case 122: - return "throw"; - case 123: - return "ldfld"; - case 124: - return "ldflda"; - case 125: - return "stfld"; - case 126: - return "ldsfld"; - case 127: - return "ldsflda"; - case 128: - return "stsfld"; - case 129: - return "stobj"; - case 130: - return "conv.ovf.i1.un"; - case 131: - return "conv.ovf.i2.un"; - case 132: - return "conv.ovf.i4.un"; - case 133: - return "conv.ovf.i8.un"; - case 134: - return "conv.ovf.u1.un"; - case 135: - return "conv.ovf.u2.un"; - case 136: - return "conv.ovf.u4.un"; - case 137: - return "conv.ovf.u8.un"; - case 138: - return "conv.ovf.i.un"; - case 139: - return "conv.ovf.u.un"; - case 140: - return "box"; - case 141: - return "newarr"; - case 142: - return "ldlen"; - case 143: - return "ldelema"; - case 144: - return "ldelem.i1"; - case 145: - return "ldelem.u1"; - case 146: - return "ldelem.i2"; - case 147: - return "ldelem.u2"; - case 148: - return "ldelem.i4"; - case 149: - return "ldelem.u4"; - case 150: - return "ldelem.i8"; - case 151: - return "ldelem.i"; - case 152: - return "ldelem.r4"; - case 153: - return "ldelem.r8"; - case 154: - return "ldelem.ref"; - case 155: - return "stelem.i"; - case 156: - return "stelem.i1"; - case 157: - return "stelem.i2"; - case 158: - return "stelem.i4"; - case 159: - return "stelem.i8"; - case 160: - return "stelem.r4"; - case 161: - return "stelem.r8"; - case 162: - return "stelem.ref"; - case 163: - return "ldelem"; - case 164: - return "stelem"; - case 165: - return "unbox.any"; - case 179: - return "conv.ovf.i1"; - case 180: - return "conv.ovf.u1"; - case 181: - return "conv.ovf.i2"; - case 182: - return "conv.ovf.u2"; - case 183: - return "conv.ovf.i4"; - case 184: - return "conv.ovf.u4"; - case 185: - return "conv.ovf.i8"; - case 186: - return "conv.ovf.u8"; - case 194: - return "refanyval"; - case 195: - return "ckfinite"; - case 198: - return "mkrefany"; - case 208: - return "ldtoken"; - case 209: - return "conv.u2"; - case 210: - return "conv.u1"; - case 211: - return "conv.i"; - case 212: - return "conv.ovf.i"; - case 213: - return "conv.ovf.u"; - case 214: - return "add.ovf"; - case 215: - return "add.ovf.un"; - case 216: - return "mul.ovf"; - case 217: - return "mul.ovf.un"; - case 218: - return "sub.ovf"; - case 219: - return "sub.ovf.un"; - case 220: - return "endfinally"; - case 221: - return "leave"; - case 222: - return "leave.s"; - case 223: - return "stind.i"; - case 224: - return "conv.u"; - case 248: - return "prefix7"; - case 249: - return "prefix6"; - case 250: - return "prefix5"; - case 251: - return "prefix4"; - case 252: - return "prefix3"; - case 253: - return "prefix2"; - case 254: - return "prefix1"; - case 255: - return "prefixref"; - case -512: - return "arglist"; - case -511: - return "ceq"; - case -510: - return "cgt"; - case -509: - return "cgt.un"; - case -508: - return "clt"; - case -507: - return "clt.un"; - case -506: - return "ldftn"; - case -505: - return "ldvirtftn"; - case -503: - return "ldarg"; - case -502: - return "ldarga"; - case -501: - return "starg"; - case -500: - return "ldloc"; - case -499: - return "ldloca"; - case -498: - return "stloc"; - case -497: - return "localloc"; - case -495: - return "endfilter"; - case -494: - return "unaligned."; - case -493: - return "volatile."; - case -492: - return "tail."; - case -491: - return "initobj"; - case -490: - return "constrained."; - case -489: - return "cpblk"; - case -488: - return "initblk"; - case -486: - return "rethrow"; - case -484: - return "sizeof"; - case -483: - return "refanytype"; - case -482: - return "readonly."; - } - throw new ArgumentOutOfRangeException(); - } - - public static bool TakesSingleByteArgument(OpCode inst) - { - switch (inst.Value) - { - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 31: - case 43: - case 44: - case 45: - case 46: - case 47: - case 48: - case 49: - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 222: - case -494: - return true; - default: - return false; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/ParameterBuilder.cs b/mcs/class/IKVM.Reflection/Emit/ParameterBuilder.cs deleted file mode 100644 index 8b01efcaa5d..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/ParameterBuilder.cs +++ /dev/null @@ -1,144 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Emit -{ - public sealed class ParameterBuilder - { - private readonly ModuleBuilder moduleBuilder; - private short flags; - private readonly short sequence; - private readonly int nameIndex; - private readonly string name; - private int lazyPseudoToken; - - internal ParameterBuilder(ModuleBuilder moduleBuilder, int sequence, ParameterAttributes attribs, string name) - { - this.moduleBuilder = moduleBuilder; - this.flags = (short)attribs; - this.sequence = (short)sequence; - this.nameIndex = name == null ? 0 : moduleBuilder.Strings.Add(name); - this.name = name; - } - - internal int PseudoToken - { - get - { - if (lazyPseudoToken == 0) - { - // we lazily create the token, because if we don't need it we don't want the token fixup cost - lazyPseudoToken = moduleBuilder.AllocPseudoToken(); - } - return lazyPseudoToken; - } - } - - public string Name - { - get { return name; } - } - - public int Position - { - // note that this differs from ParameterInfo.Position, which is zero based - get { return sequence; } - } - - public int Attributes - { - get { return flags; } - } - - public bool IsIn - { - get { return (flags & (short)ParameterAttributes.In) != 0; } - } - - public bool IsOut - { - get { return (flags & (short)ParameterAttributes.Out) != 0; } - } - - public bool IsOptional - { - get { return (flags & (short)ParameterAttributes.Optional) != 0; } - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customAttributeBuilder) - { - Universe u = moduleBuilder.universe; - if (customAttributeBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_InAttribute) - { - flags |= (short)ParameterAttributes.In; - } - else if (customAttributeBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_OutAttribute) - { - flags |= (short)ParameterAttributes.Out; - } - else if (customAttributeBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_OptionalAttribute) - { - flags |= (short)ParameterAttributes.Optional; - } - else if (customAttributeBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute) - { - FieldMarshal.SetMarshalAsAttribute(moduleBuilder, PseudoToken, customAttributeBuilder); - flags |= (short)ParameterAttributes.HasFieldMarshal; - } - else - { - moduleBuilder.SetCustomAttribute(PseudoToken, customAttributeBuilder); - } - } - - public void SetConstant(object defaultValue) - { - flags |= (short)ParameterAttributes.HasDefault; - moduleBuilder.AddConstant(PseudoToken, defaultValue); - } - - internal void WriteParamRecord(MetadataWriter mw) - { - mw.Write(flags); - mw.Write(sequence); - mw.WriteStringIndex(nameIndex); - } - - internal void FixupToken(int parameterToken) - { - if (lazyPseudoToken != 0) - { - moduleBuilder.RegisterTokenFixup(lazyPseudoToken, parameterToken); - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs b/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs deleted file mode 100644 index 2900f7abb5f..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/PropertyBuilder.cs +++ /dev/null @@ -1,288 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Emit -{ - public sealed class PropertyBuilder : PropertyInfo - { - private readonly TypeBuilder typeBuilder; - private readonly string name; - private PropertyAttributes attributes; - private PropertySignature sig; - private MethodBuilder getter; - private MethodBuilder setter; - private readonly List accessors = new List(); - private int lazyPseudoToken; - private bool patchCallingConvention; - - private struct Accessor - { - internal short Semantics; - internal MethodBuilder Method; - } - - internal PropertyBuilder(TypeBuilder typeBuilder, string name, PropertyAttributes attributes, PropertySignature sig, bool patchCallingConvention) - { - this.typeBuilder = typeBuilder; - this.name = name; - this.attributes = attributes; - this.sig = sig; - this.patchCallingConvention = patchCallingConvention; - } - - internal override PropertySignature PropertySignature - { - get { return sig; } - } - - public void SetGetMethod(MethodBuilder mdBuilder) - { - getter = mdBuilder; - Accessor acc; - acc.Semantics = MethodSemanticsTable.Getter; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void SetSetMethod(MethodBuilder mdBuilder) - { - setter = mdBuilder; - Accessor acc; - acc.Semantics = MethodSemanticsTable.Setter; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void AddOtherMethod(MethodBuilder mdBuilder) - { - Accessor acc; - acc.Semantics = MethodSemanticsTable.Other; - acc.Method = mdBuilder; - accessors.Add(acc); - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - Universe u = typeBuilder.ModuleBuilder.universe; - if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute) - { - attributes |= PropertyAttributes.SpecialName; - } - else - { - if (lazyPseudoToken == 0) - { - lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); - } - typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder); - } - } - - public override object GetRawConstantValue() - { - if (lazyPseudoToken != 0) - { - return typeBuilder.ModuleBuilder.Constant.GetRawConstantValue(typeBuilder.ModuleBuilder, lazyPseudoToken); - } - throw new InvalidOperationException(); - } - - public override PropertyAttributes Attributes - { - get { return attributes; } - } - - public override bool CanRead - { - get { return getter != null; } - } - - public override bool CanWrite - { - get { return setter != null; } - } - - public override MethodInfo GetGetMethod(bool nonPublic) - { - return nonPublic || (getter != null && getter.IsPublic) ? getter : null; - } - - public override MethodInfo GetSetMethod(bool nonPublic) - { - return nonPublic || (setter != null && setter.IsPublic) ? setter : null; - } - - public override MethodInfo[] GetAccessors(bool nonPublic) - { - List list = new List(); - foreach (Accessor acc in accessors) - { - AddAccessor(list, nonPublic, acc.Method); - } - return list.ToArray(); - } - - private static void AddAccessor(List list, bool nonPublic, MethodInfo method) - { - if (method != null && (nonPublic || method.IsPublic)) - { - list.Add(method); - } - } - - public override Type DeclaringType - { - get { return typeBuilder; } - } - - public override string Name - { - get { return name; } - } - - public override Module Module - { - get { return typeBuilder.Module; } - } - - public void SetConstant(object defaultValue) - { - if (lazyPseudoToken == 0) - { - lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); - } - attributes |= PropertyAttributes.HasDefault; - typeBuilder.ModuleBuilder.AddConstant(lazyPseudoToken, defaultValue); - } - - internal void Bake() - { - if (patchCallingConvention) - { - sig.HasThis = !this.IsStatic; - } - - PropertyTable.Record rec = new PropertyTable.Record(); - rec.Flags = (short)attributes; - rec.Name = typeBuilder.ModuleBuilder.Strings.Add(name); - rec.Type = typeBuilder.ModuleBuilder.GetSignatureBlobIndex(sig); - int token = 0x17000000 | typeBuilder.ModuleBuilder.Property.AddRecord(rec); - - if (lazyPseudoToken == 0) - { - lazyPseudoToken = token; - } - else - { - typeBuilder.ModuleBuilder.RegisterTokenFixup(lazyPseudoToken, token); - } - - foreach (Accessor acc in accessors) - { - AddMethodSemantics(acc.Semantics, acc.Method.MetadataToken, token); - } - } - - private void AddMethodSemantics(short semantics, int methodToken, int propertyToken) - { - MethodSemanticsTable.Record rec = new MethodSemanticsTable.Record(); - rec.Semantics = semantics; - rec.Method = methodToken; - rec.Association = propertyToken; - typeBuilder.ModuleBuilder.MethodSemantics.AddRecord(rec); - } - - internal override bool IsPublic - { - get - { - foreach (Accessor acc in accessors) - { - if (acc.Method.IsPublic) - { - return true; - } - } - return false; - } - } - - internal override bool IsNonPrivate - { - get - { - foreach (Accessor acc in accessors) - { - if ((acc.Method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private) - { - return true; - } - } - return false; - } - } - - internal override bool IsStatic - { - get - { - foreach (Accessor acc in accessors) - { - if (acc.Method.IsStatic) - { - return true; - } - } - return false; - } - } - - internal override bool IsBaked - { - get { return typeBuilder.IsBaked; } - } - - internal override int GetCurrentToken() - { - if (typeBuilder.ModuleBuilder.IsSaved && typeBuilder.ModuleBuilder.IsPseudoToken(lazyPseudoToken)) - { - return typeBuilder.ModuleBuilder.ResolvePseudoToken(lazyPseudoToken); - } - else - { - return lazyPseudoToken; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs b/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs deleted file mode 100644 index b70ace82169..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/SignatureHelper.cs +++ /dev/null @@ -1,317 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using IKVM.Reflection; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public abstract class SignatureHelper - { - protected readonly byte type; - protected ushort paramCount; - - sealed class Lazy : SignatureHelper - { - private readonly List args = new List(); - - internal Lazy(byte type) - : base(type) - { - } - - internal override Type ReturnType - { - get { return args[0]; } - } - - public override byte[] GetSignature() - { - throw new NotSupportedException(); - } - - internal override ByteBuffer GetSignature(ModuleBuilder module) - { - ByteBuffer bb = new ByteBuffer(16); - Signature.WriteSignatureHelper(module, bb, type, paramCount, args); - return bb; - } - - public override void AddSentinel() - { - args.Add(MarkerType.Sentinel); - } - - public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers) - { - if (pinned) - { - args.Add(MarkerType.Pinned); - } - foreach (CustomModifiers.Entry mod in customModifiers) - { - args.Add(mod.IsRequired ? MarkerType.ModReq : MarkerType.ModOpt); - args.Add(mod.Type); - } - args.Add(argument); - paramCount++; - } - } - - sealed class Eager : SignatureHelper - { - private readonly ModuleBuilder module; - private readonly ByteBuffer bb = new ByteBuffer(16); - private readonly Type returnType; - - internal Eager(ModuleBuilder module, byte type, Type returnType) - : base(type) - { - this.module = module; - this.returnType = returnType; - bb.Write(type); - if (type != Signature.FIELD) - { - // space for parameterCount - bb.Write((byte)0); - } - } - - internal override Type ReturnType - { - get { return returnType; } - } - - public override byte[] GetSignature() - { - return GetSignature(null).ToArray(); - } - - internal override ByteBuffer GetSignature(ModuleBuilder module) - { - if (type != Signature.FIELD) - { - bb.Position = 1; - bb.Insert(MetadataWriter.GetCompressedIntLength(paramCount) - bb.GetCompressedIntLength()); - bb.WriteCompressedInt(paramCount); - } - return bb; - } - - public override void AddSentinel() - { - bb.Write(Signature.SENTINEL); - } - - public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers) - { - if (pinned) - { - bb.Write(Signature.ELEMENT_TYPE_PINNED); - } - foreach (CustomModifiers.Entry mod in customModifiers) - { - bb.Write(mod.IsRequired ? Signature.ELEMENT_TYPE_CMOD_REQD : Signature.ELEMENT_TYPE_CMOD_OPT); - Signature.WriteTypeSpec(module, bb, mod.Type); - } - Signature.WriteTypeSpec(module, bb, argument ?? module.universe.System_Void); - paramCount++; - } - } - - private SignatureHelper(byte type) - { - this.type = type; - } - - internal bool HasThis - { - get { return (type & Signature.HASTHIS) != 0; } - } - - internal abstract Type ReturnType - { - get; - } - - internal int ParameterCount - { - get { return paramCount; } - } - - private static SignatureHelper Create(Module mod, byte type, Type returnType) - { - ModuleBuilder mb = mod as ModuleBuilder; - return mb == null - ? (SignatureHelper)new Lazy(type) - : new Eager(mb, type, returnType); - } - - public static SignatureHelper GetFieldSigHelper(Module mod) - { - return Create(mod, Signature.FIELD, null); - } - - public static SignatureHelper GetLocalVarSigHelper() - { - return new Lazy(Signature.LOCAL_SIG); - } - - public static SignatureHelper GetLocalVarSigHelper(Module mod) - { - return Create(mod, Signature.LOCAL_SIG, null); - } - - public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes) - { - SignatureHelper sig = Create(mod, Signature.PROPERTY, returnType); - sig.AddArgument(returnType); - sig.paramCount = 0; - sig.AddArguments(parameterTypes, null, null); - return sig; - } - - public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) - { - return GetPropertySigHelper(mod, CallingConventions.Standard, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); - } - - public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) - { - byte type = Signature.PROPERTY; - if ((callingConvention & CallingConventions.HasThis) != 0) - { - type |= Signature.HASTHIS; - } - SignatureHelper sig = Create(mod, type, returnType); - sig.AddArgument(returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); - sig.paramCount = 0; - sig.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); - return sig; - } - - public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType) - { - return GetMethodSigHelper(null, unmanagedCallingConvention, returnType); - } - - public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType) - { - return GetMethodSigHelper(null, callingConvention, returnType); - } - - public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType) - { - byte type; - switch (unmanagedCallConv) - { - case CallingConvention.Cdecl: - type = 0x01; // C - break; - case CallingConvention.StdCall: - case CallingConvention.Winapi: - type = 0x02; // STDCALL - break; - case CallingConvention.ThisCall: - type = 0x03; // THISCALL - break; - case CallingConvention.FastCall: - type = 0x04; // FASTCALL - break; - default: - throw new ArgumentOutOfRangeException("unmanagedCallConv"); - } - SignatureHelper sig = Create(mod, type, returnType); - sig.AddArgument(returnType); - sig.paramCount = 0; - return sig; - } - - public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType) - { - byte type = 0; - if ((callingConvention & CallingConventions.HasThis) != 0) - { - type |= Signature.HASTHIS; - } - if ((callingConvention & CallingConventions.ExplicitThis) != 0) - { - type |= Signature.EXPLICITTHIS; - } - if ((callingConvention & CallingConventions.VarArgs) != 0) - { - type |= Signature.VARARG; - } - SignatureHelper sig = Create(mod, type, returnType); - sig.AddArgument(returnType); - sig.paramCount = 0; - return sig; - } - - public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes) - { - SignatureHelper sig = Create(mod, 0, returnType); - sig.AddArgument(returnType); - sig.paramCount = 0; - sig.AddArguments(parameterTypes, null, null); - return sig; - } - - public abstract byte[] GetSignature(); - - internal abstract ByteBuffer GetSignature(ModuleBuilder module); - - public abstract void AddSentinel(); - - public void AddArgument(Type clsArgument) - { - AddArgument(clsArgument, false); - } - - public void AddArgument(Type argument, bool pinned) - { - __AddArgument(argument, pinned, new CustomModifiers()); - } - - public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - __AddArgument(argument, false, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public abstract void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers); - - public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) - { - if (arguments != null) - { - for (int i = 0; i < arguments.Length; i++) - { - __AddArgument(arguments[i], false, CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i))); - } - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/Tokens.cs b/mcs/class/IKVM.Reflection/Emit/Tokens.cs deleted file mode 100644 index 49ac4c6adb9..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/Tokens.cs +++ /dev/null @@ -1,281 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ - -namespace IKVM.Reflection.Emit -{ - public struct EventToken - { - public static readonly EventToken Empty; - private readonly int token; - - internal EventToken(int token) - { - this.token = token; - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as EventToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(EventToken other) - { - return this == other; - } - - public static bool operator ==(EventToken et1, EventToken et2) - { - return et1.token == et2.token; - } - - public static bool operator !=(EventToken et1, EventToken et2) - { - return et1.token != et2.token; - } - } - - public struct FieldToken - { - public static readonly FieldToken Empty; - private readonly int token; - - internal FieldToken(int token) - { - this.token = token; - } - - internal bool IsPseudoToken - { - get { return token < 0; } - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as FieldToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(FieldToken other) - { - return this == other; - } - - public static bool operator ==(FieldToken ft1, FieldToken ft2) - { - return ft1.token == ft2.token; - } - - public static bool operator !=(FieldToken ft1, FieldToken ft2) - { - return ft1.token != ft2.token; - } - } - - public struct MethodToken - { - public static readonly MethodToken Empty; - private readonly int token; - - internal MethodToken(int token) - { - this.token = token; - } - - internal bool IsPseudoToken - { - get { return token < 0; } - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as MethodToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(MethodToken other) - { - return this == other; - } - - public static bool operator ==(MethodToken mt1, MethodToken mt2) - { - return mt1.token == mt2.token; - } - - public static bool operator !=(MethodToken mt1, MethodToken mt2) - { - return mt1.token != mt2.token; - } - } - - public struct SignatureToken - { - public static readonly SignatureToken Empty; - private readonly int token; - - internal SignatureToken(int token) - { - this.token = token; - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as SignatureToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(SignatureToken other) - { - return this == other; - } - - public static bool operator ==(SignatureToken st1, SignatureToken st2) - { - return st1.token == st2.token; - } - - public static bool operator !=(SignatureToken st1, SignatureToken st2) - { - return st1.token != st2.token; - } - } - - public struct StringToken - { - private readonly int token; - - internal StringToken(int token) - { - this.token = token; - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as StringToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(StringToken other) - { - return this == other; - } - - public static bool operator ==(StringToken st1, StringToken st2) - { - return st1.token == st2.token; - } - - public static bool operator !=(StringToken st1, StringToken st2) - { - return st1.token != st2.token; - } - } - - public struct TypeToken - { - public static readonly TypeToken Empty; - private readonly int token; - - internal TypeToken(int token) - { - this.token = token; - } - - public int Token - { - get { return token; } - } - - public override bool Equals(object obj) - { - return obj as TypeToken? == this; - } - - public override int GetHashCode() - { - return token; - } - - public bool Equals(TypeToken other) - { - return this == other; - } - - public static bool operator ==(TypeToken tt1, TypeToken tt2) - { - return tt1.token == tt2.token; - } - - public static bool operator !=(TypeToken tt1, TypeToken tt2) - { - return tt1.token != tt2.token; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs b/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs deleted file mode 100644 index b9f2a8f4b78..00000000000 --- a/mcs/class/IKVM.Reflection/Emit/TypeBuilder.cs +++ /dev/null @@ -1,1242 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.InteropServices; -using IKVM.Reflection.Impl; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Writer; - -namespace IKVM.Reflection.Emit -{ - public sealed class GenericTypeParameterBuilder : TypeInfo - { - private readonly string name; - private readonly TypeBuilder type; - private readonly MethodBuilder method; - private readonly int paramPseudoIndex; - private readonly int position; - private int typeToken; - private Type baseType; - private GenericParameterAttributes attr; - - internal GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position) - { - this.name = name; - this.type = type; - this.method = method; - this.position = position; - GenericParamTable.Record rec = new GenericParamTable.Record(); - rec.Number = (short)position; - rec.Flags = 0; - rec.Owner = type != null ? type.MetadataToken : method.MetadataToken; - rec.Name = this.ModuleBuilder.Strings.Add(name); - this.paramPseudoIndex = this.ModuleBuilder.GenericParam.AddRecord(rec); - } - - public override string AssemblyQualifiedName - { - get { return null; } - } - - public override bool IsValueType - { - get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; } - } - - public override Type BaseType - { - get { return baseType; } - } - - public override Type[] __GetDeclaredInterfaces() - { - throw new NotImplementedException(); - } - - public override TypeAttributes Attributes - { - get { return TypeAttributes.Public; } - } - - public override string Namespace - { - get { return DeclaringType.Namespace; } - } - - public override string Name - { - get { return name; } - } - - public override string FullName - { - get { return null; } - } - - public override string ToString() - { - return this.Name; - } - - private ModuleBuilder ModuleBuilder - { - get { return type != null ? type.ModuleBuilder : method.ModuleBuilder; } - } - - public override Module Module - { - get { return ModuleBuilder; } - } - - public override bool IsGenericParameter - { - get { return true; } - } - - public override int GenericParameterPosition - { - get { return position; } - } - - public override Type DeclaringType - { - get { return type; } - } - - public override MethodBase DeclaringMethod - { - get { return method; } - } - - public override Type[] GetGenericParameterConstraints() - { - throw new NotImplementedException(); - } - - public override GenericParameterAttributes GenericParameterAttributes - { - get - { - CheckBaked(); - return attr; - } - } - - internal override void CheckBaked() - { - if (type != null) - { - type.CheckBaked(); - } - else - { - method.CheckBaked(); - } - } - - private void AddConstraint(Type type) - { - GenericParamConstraintTable.Record rec = new GenericParamConstraintTable.Record(); - rec.Owner = paramPseudoIndex; - rec.Constraint = this.ModuleBuilder.GetTypeTokenForMemberRef(type); - this.ModuleBuilder.GenericParamConstraint.AddRecord(rec); - } - - public void SetBaseTypeConstraint(Type baseTypeConstraint) - { - this.baseType = baseTypeConstraint; - AddConstraint(baseTypeConstraint); - } - - public void SetInterfaceConstraints(params Type[] interfaceConstraints) - { - foreach (Type type in interfaceConstraints) - { - AddConstraint(type); - } - } - - public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes) - { - this.attr = genericParameterAttributes; - // for now we'll back patch the table - this.ModuleBuilder.GenericParam.PatchAttribute(paramPseudoIndex, genericParameterAttributes); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - this.ModuleBuilder.SetCustomAttribute((GenericParamTable.Index << 24) | paramPseudoIndex, customBuilder); - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public override int MetadataToken - { - get - { - CheckBaked(); - return (GenericParamTable.Index << 24) | paramPseudoIndex; - } - } - - internal override int GetModuleBuilderToken() - { - if (typeToken == 0) - { - ByteBuffer spec = new ByteBuffer(5); - Signature.WriteTypeSpec(this.ModuleBuilder, spec, this); - typeToken = 0x1B000000 | this.ModuleBuilder.TypeSpec.AddRecord(this.ModuleBuilder.Blobs.Add(spec)); - } - return typeToken; - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - if (type != null) - { - return binder.BindTypeParameter(this); - } - else - { - return binder.BindMethodParameter(this); - } - } - - internal override int GetCurrentToken() - { - if (this.ModuleBuilder.IsSaved) - { - return (GenericParamTable.Index << 24) | this.Module.GenericParam.GetIndexFixup()[paramPseudoIndex - 1] + 1; - } - else - { - return (GenericParamTable.Index << 24) | paramPseudoIndex; - } - } - - internal override bool IsBaked - { - get { return ((MemberInfo)type ?? method).IsBaked; } - } - } - - public sealed class TypeBuilder : TypeInfo, ITypeOwner - { - public const int UnspecifiedTypeSize = 0; - private readonly ITypeOwner owner; - private readonly int token; - private int extends; - private Type lazyBaseType; // (lazyBaseType == null && attribs & TypeAttributes.Interface) == 0) => BaseType == System.Object - private readonly int typeName; - private readonly int typeNameSpace; - private readonly string ns; - private readonly string name; - private readonly List methods = new List(); - private readonly List fields = new List(); - private List properties; - private List events; - private TypeAttributes attribs; - private GenericTypeParameterBuilder[] gtpb; - private List declarativeSecurity; - private List interfaces; - private int size; - private short pack; - private bool hasLayout; - - internal TypeBuilder(ITypeOwner owner, string ns, string name) - { - this.owner = owner; - this.token = this.ModuleBuilder.TypeDef.AllocToken(); - this.ns = ns; - this.name = name; - this.typeNameSpace = ns == null ? 0 : this.ModuleBuilder.Strings.Add(ns); - this.typeName = this.ModuleBuilder.Strings.Add(name); - MarkEnumOrValueType(ns, name); - } - - public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) - { - ConstructorBuilder cb = DefineConstructor(attributes, CallingConventions.Standard, Type.EmptyTypes); - ILGenerator ilgen = cb.GetILGenerator(); - ilgen.Emit(OpCodes.Ldarg_0); - ilgen.Emit(OpCodes.Call, BaseType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); - ilgen.Emit(OpCodes.Ret); - return cb; - } - - public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callConv, Type[] parameterTypes) - { - return DefineConstructor(attribs, callConv, parameterTypes, null, null); - } - - public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) - { - attribs |= MethodAttributes.RTSpecialName | MethodAttributes.SpecialName; - string name = (attribs & MethodAttributes.Static) == 0 ? ConstructorInfo.ConstructorName : ConstructorInfo.TypeConstructorName; - MethodBuilder mb = DefineMethod(name, attribs, callingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); - return new ConstructorBuilder(mb); - } - - public ConstructorBuilder DefineTypeInitializer() - { - MethodBuilder mb = DefineMethod(ConstructorInfo.TypeConstructorName, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, null, Type.EmptyTypes); - return new ConstructorBuilder(mb); - } - - private MethodBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention) - { - this.ModuleBuilder.MethodDef.AddVirtualRecord(); - MethodBuilder mb = new MethodBuilder(this, name, attributes, callingConvention); - methods.Add(mb); - return mb; - } - - public MethodBuilder DefineMethod(string name, MethodAttributes attribs) - { - return DefineMethod(name, attribs, CallingConventions.Standard); - } - - public MethodBuilder DefineMethod(string name, MethodAttributes attribs, CallingConventions callingConvention) - { - return CreateMethodBuilder(name, attribs, callingConvention); - } - - public MethodBuilder DefineMethod(string name, MethodAttributes attribs, Type returnType, Type[] parameterTypes) - { - return DefineMethod(name, attribs, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null); - } - - public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - { - return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); - } - - public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - MethodBuilder mb = CreateMethodBuilder(name, attributes, callingConvention); - mb.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); - return mb; - } - - public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) - { - return DefinePInvokeMethod(name, dllName, null, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet); - } - - public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) - { - return DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet); - } - - public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, - Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, - Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, - CallingConvention nativeCallConv, CharSet nativeCharSet) - { - MethodBuilder mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention, - returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, - parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); - mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet, null, null, null, null, null); - return mb; - } - - public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) - { - MethodImplTable.Record rec = new MethodImplTable.Record(); - rec.Class = token; - rec.MethodBody = this.ModuleBuilder.GetMethodToken(methodInfoBody).Token; - rec.MethodDeclaration = this.ModuleBuilder.GetMethodTokenWinRT(methodInfoDeclaration); - this.ModuleBuilder.MethodImpl.AddRecord(rec); - } - - public FieldBuilder DefineField(string name, Type fieldType, FieldAttributes attribs) - { - return DefineField(name, fieldType, null, null, attribs); - } - - public FieldBuilder DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) - { - return __DefineField(fieldName, type, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers), attributes); - } - - public FieldBuilder __DefineField(string fieldName, Type type, CustomModifiers customModifiers, FieldAttributes attributes) - { - FieldBuilder fb = new FieldBuilder(this, fieldName, type, customModifiers, attributes); - fields.Add(fb); - return fb; - } - - public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) - { - return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null); - } - - public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, - Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - return DefinePropertyImpl(name, attributes, CallingConventions.Standard, true, returnType, parameterTypes, - PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, - Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, - Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes, - PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - public PropertyBuilder __DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, - Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes, - PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - private PropertyBuilder DefinePropertyImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, bool patchCallingConvention, - Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) - { - if (properties == null) - { - properties = new List(); - } - PropertySignature sig = PropertySignature.Create(callingConvention, returnType, parameterTypes, customModifiers); - PropertyBuilder pb = new PropertyBuilder(this, name, attributes, sig, patchCallingConvention); - properties.Add(pb); - return pb; - } - - public EventBuilder DefineEvent(string name, EventAttributes attributes, Type eventtype) - { - if (events == null) - { - events = new List(); - } - EventBuilder eb = new EventBuilder(this, name, attributes, eventtype); - events.Add(eb); - return eb; - } - - public TypeBuilder DefineNestedType(string name) - { - return DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPrivate); - } - - public TypeBuilder DefineNestedType(string name, TypeAttributes attribs) - { - return DefineNestedType(name, attribs, null); - } - - public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces) - { - TypeBuilder tb = DefineNestedType(name, attr, parent); - if (interfaces != null) - { - foreach (Type iface in interfaces) - { - tb.AddInterfaceImplementation(iface); - } - } - return tb; - } - - public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent) - { - return DefineNestedType(name, attr, parent, 0); - } - - public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize) - { - return DefineNestedType(name, attr, parent, PackingSize.Unspecified, typeSize); - } - - public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize) - { - return DefineNestedType(name, attr, parent, packSize, 0); - } - - private TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize) - { - string ns = null; - int lastdot = name.LastIndexOf('.'); - if (lastdot > 0) - { - ns = name.Substring(0, lastdot); - name = name.Substring(lastdot + 1); - } - TypeBuilder typeBuilder = __DefineNestedType(ns, name); - typeBuilder.__SetAttributes(attr); - typeBuilder.SetParent(parent); - if (packSize != PackingSize.Unspecified || typeSize != 0) - { - typeBuilder.__SetLayout((int)packSize, typeSize); - } - return typeBuilder; - } - - public TypeBuilder __DefineNestedType(string ns, string name) - { - this.typeFlags |= TypeFlags.HasNestedTypes; - TypeBuilder typeBuilder = this.ModuleBuilder.DefineType(this, ns, name); - NestedClassTable.Record rec = new NestedClassTable.Record(); - rec.NestedClass = typeBuilder.MetadataToken; - rec.EnclosingClass = this.MetadataToken; - this.ModuleBuilder.NestedClass.AddRecord(rec); - return typeBuilder; - } - - public void SetParent(Type parent) - { - lazyBaseType = parent; - } - - public void AddInterfaceImplementation(Type interfaceType) - { - if (interfaces == null) - { - interfaces = new List(); - } - interfaces.Add(interfaceType); - } - - public void __SetInterfaceImplementationCustomAttribute(Type interfaceType, CustomAttributeBuilder cab) - { - this.ModuleBuilder.SetInterfaceImplementationCustomAttribute(this, interfaceType, cab); - } - - public int Size - { - get { return size; } - } - - public PackingSize PackingSize - { - get { return (PackingSize)pack; } - } - - public override bool __GetLayout(out int packingSize, out int typeSize) - { - packingSize = this.pack; - typeSize = this.size; - return hasLayout; - } - - public void __SetLayout(int packingSize, int typesize) - { - this.pack = (short)packingSize; - this.size = typesize; - this.hasLayout = true; - } - - private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder) - { - object val = customBuilder.GetConstructorArgument(0); - LayoutKind layout; - if (val is short) - { - layout = (LayoutKind)(short)val; - } - else - { - layout = (LayoutKind)val; - } - StructLayoutAttribute attr = new StructLayoutAttribute(layout); - attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0; - attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0; - attr.CharSet = customBuilder.GetFieldValue("CharSet") ?? CharSet.None; - attribs &= ~TypeAttributes.LayoutMask; - switch (attr.Value) - { - case LayoutKind.Auto: - attribs |= TypeAttributes.AutoLayout; - break; - case LayoutKind.Explicit: - attribs |= TypeAttributes.ExplicitLayout; - break; - case LayoutKind.Sequential: - attribs |= TypeAttributes.SequentialLayout; - break; - } - attribs &= ~TypeAttributes.StringFormatMask; - switch (attr.CharSet) - { - case CharSet.None: - case CharSet.Ansi: - attribs |= TypeAttributes.AnsiClass; - break; - case CharSet.Auto: - attribs |= TypeAttributes.AutoClass; - break; - case CharSet.Unicode: - attribs |= TypeAttributes.UnicodeClass; - break; - } - pack = (short)attr.Pack; - size = attr.Size; - hasLayout = pack != 0 || size != 0; - } - - public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) - { - SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); - } - - public void SetCustomAttribute(CustomAttributeBuilder customBuilder) - { - Universe u = this.ModuleBuilder.universe; - Type type = customBuilder.Constructor.DeclaringType; - if (type == u.System_Runtime_InteropServices_StructLayoutAttribute) - { - SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(this.Assembly)); - } - else if (type == u.System_SerializableAttribute) - { - attribs |= TypeAttributes.Serializable; - } - else if (type == u.System_Runtime_InteropServices_ComImportAttribute) - { - attribs |= TypeAttributes.Import; - } - else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute) - { - attribs |= TypeAttributes.SpecialName; - } - else - { - if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute) - { - attribs |= TypeAttributes.HasSecurity; - } - this.ModuleBuilder.SetCustomAttribute(token, customBuilder); - } - } - - public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) - { - attribs |= TypeAttributes.HasSecurity; - if (declarativeSecurity == null) - { - declarativeSecurity = new List(); - } - declarativeSecurity.Add(customBuilder); - } - - public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet) - { - this.ModuleBuilder.AddDeclarativeSecurity(token, securityAction, permissionSet); - this.attribs |= TypeAttributes.HasSecurity; - } - - public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) - { - typeFlags |= TypeFlags.IsGenericTypeDefinition; - gtpb = new GenericTypeParameterBuilder[names.Length]; - for (int i = 0; i < names.Length; i++) - { - gtpb[i] = new GenericTypeParameterBuilder(names[i], this, null, i); - } - return (GenericTypeParameterBuilder[])gtpb.Clone(); - } - - public override Type[] GetGenericArguments() - { - return Util.Copy(gtpb); - } - - public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - return gtpb == null ? Empty.Array : new CustomModifiers[gtpb.Length]; - } - - internal override Type GetGenericTypeArgument(int index) - { - return gtpb[index]; - } - - public override bool ContainsGenericParameters - { - get { return gtpb != null; } - } - - public override Type GetGenericTypeDefinition() - { - return this; - } - - public Type CreateType() - { - if ((typeFlags & TypeFlags.Baked) != 0) - { - // .NET allows multiple invocations (subsequent invocations return the same baked type) - throw new NotImplementedException(); - } - typeFlags |= TypeFlags.Baked; - if (hasLayout) - { - ClassLayoutTable.Record rec = new ClassLayoutTable.Record(); - rec.PackingSize = pack; - rec.ClassSize = size; - rec.Parent = token; - this.ModuleBuilder.ClassLayout.AddRecord(rec); - } - bool hasConstructor = false; - foreach (MethodBuilder mb in methods) - { - hasConstructor |= mb.IsSpecialName && mb.Name == ConstructorInfo.ConstructorName; - mb.Bake(); - } - if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed)) - { - ((MethodBuilder)DefineDefaultConstructor(MethodAttributes.Public).GetMethodInfo()).Bake(); - } - if (declarativeSecurity != null) - { - this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity); - } - if (!IsModulePseudoType) - { - Type baseType = this.BaseType; - if (baseType != null) - { - extends = this.ModuleBuilder.GetTypeToken(baseType).Token; - } - } - if (interfaces != null) - { - foreach (Type interfaceType in interfaces) - { - InterfaceImplTable.Record rec = new InterfaceImplTable.Record(); - rec.Class = token; - rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token; - this.ModuleBuilder.InterfaceImpl.AddRecord(rec); - } - } - return new BakedType(this); - } - - internal void PopulatePropertyAndEventTables() - { - if (properties != null) - { - PropertyMapTable.Record rec = new PropertyMapTable.Record(); - rec.Parent = token; - rec.PropertyList = this.ModuleBuilder.Property.RowCount + 1; - this.ModuleBuilder.PropertyMap.AddRecord(rec); - foreach (PropertyBuilder pb in properties) - { - pb.Bake(); - } - } - if (events != null) - { - EventMapTable.Record rec = new EventMapTable.Record(); - rec.Parent = token; - rec.EventList = this.ModuleBuilder.Event.RowCount + 1; - this.ModuleBuilder.EventMap.AddRecord(rec); - foreach (EventBuilder eb in events) - { - eb.Bake(); - } - } - } - - public override Type BaseType - { - get - { - if (lazyBaseType == null && !IsInterface) - { - Type obj = Module.universe.System_Object; - if (this != obj) - { - lazyBaseType = obj; - } - } - return lazyBaseType; - } - } - - public override string FullName - { - get - { - if (this.IsNested) - { - return this.DeclaringType.FullName + "+" + TypeNameParser.Escape(name); - } - if (ns == null) - { - return TypeNameParser.Escape(name); - } - else - { - return TypeNameParser.Escape(ns) + "." + TypeNameParser.Escape(name); - } - } - } - - public override string __Name - { - get { return name; } - } - - public override string __Namespace - { - get { return ns; } - } - - public override string Name - { - // FXBUG for a TypeBuilder the name is not escaped - get { return name; } - } - - public override string Namespace - { - get - { - // for some reason, TypeBuilder doesn't return null (and mcs depends on this) - // note also that we don't return the declaring type namespace for nested types - return ns ?? ""; - } - } - - public override TypeAttributes Attributes - { - get { return attribs; } - } - - public void __SetAttributes(TypeAttributes attributes) - { - this.attribs = attributes; - } - - public override Type[] __GetDeclaredInterfaces() - { - return Util.ToArray(interfaces, Type.EmptyTypes); - } - - public override MethodBase[] __GetDeclaredMethods() - { - MethodBase[] methods = new MethodBase[this.methods.Count]; - for (int i = 0; i < methods.Length; i++) - { - MethodBuilder mb = this.methods[i]; - if (mb.IsConstructor) - { - methods[i] = new ConstructorInfoImpl(mb); - } - else - { - methods[i] = mb; - } - } - return methods; - } - - public override StructLayoutAttribute StructLayoutAttribute - { - get - { - LayoutKind layout; - switch (attribs & TypeAttributes.LayoutMask) - { - case TypeAttributes.ExplicitLayout: - layout = LayoutKind.Explicit; - break; - case TypeAttributes.SequentialLayout: - layout = LayoutKind.Sequential; - break; - default: - layout = LayoutKind.Auto; - break; - } - StructLayoutAttribute attr = new StructLayoutAttribute(layout); - attr.Pack = (ushort)pack; - attr.Size = size; - switch (attribs & TypeAttributes.StringFormatMask) - { - case TypeAttributes.AutoClass: - attr.CharSet = CharSet.Auto; - break; - case TypeAttributes.UnicodeClass: - attr.CharSet = CharSet.Unicode; - break; - case TypeAttributes.AnsiClass: - attr.CharSet = CharSet.Ansi; - break; - default: - attr.CharSet = CharSet.None; - break; - } - return attr; - } - } - - public override Type DeclaringType - { - get { return owner as TypeBuilder; } - } - - public override bool IsGenericType - { - get { return IsGenericTypeDefinition; } - } - - public override bool IsGenericTypeDefinition - { - get { return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; } - } - - public override int MetadataToken - { - get { return token; } - } - - public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes) - { - return DefineInitializedData(name, new byte[size], attributes); - } - - public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes) - { - Type fieldType = this.ModuleBuilder.GetType("$ArrayType$" + data.Length); - if (fieldType == null) - { - TypeBuilder tb = this.ModuleBuilder.DefineType("$ArrayType$" + data.Length, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.ExplicitLayout, this.Module.universe.System_ValueType, PackingSize.Size1, data.Length); - tb.CreateType(); - fieldType = tb; - } - FieldBuilder fb = DefineField(name, fieldType, attributes | FieldAttributes.Static); - fb.__SetDataAndRVA(data); - return fb; - } - - public static MethodInfo GetMethod(Type type, MethodInfo method) - { - return new GenericMethodInstance(type, method, null); - } - - public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) - { - return new ConstructorInfoImpl(GetMethod(type, constructor.GetMethodInfo())); - } - - public static FieldInfo GetField(Type type, FieldInfo field) - { - return new GenericFieldInstance(type, field); - } - - public override Module Module - { - get { return owner.ModuleBuilder; } - } - - public TypeToken TypeToken - { - get { return new TypeToken(token); } - } - - internal void WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList) - { - mw.Write((int)attribs); - mw.WriteStringIndex(typeName); - mw.WriteStringIndex(typeNameSpace); - mw.WriteTypeDefOrRef(extends); - mw.WriteField(fieldList); - mw.WriteMethodDef(methodList); - methodList += methods.Count; - fieldList += fields.Count; - } - - internal void WriteMethodDefRecords(int baseRVA, MetadataWriter mw, ref int paramList) - { - foreach (MethodBuilder mb in methods) - { - mb.WriteMethodDefRecord(baseRVA, mw, ref paramList); - } - } - - internal void ResolveMethodAndFieldTokens(ref int methodToken, ref int fieldToken, ref int parameterToken) - { - foreach (MethodBuilder method in methods) - { - method.FixupToken(methodToken++, ref parameterToken); - } - foreach (FieldBuilder field in fields) - { - field.FixupToken(fieldToken++); - } - } - - internal void WriteParamRecords(MetadataWriter mw) - { - foreach (MethodBuilder mb in methods) - { - mb.WriteParamRecords(mw); - } - } - - internal void WriteFieldRecords(MetadataWriter mw) - { - foreach (FieldBuilder fb in fields) - { - fb.WriteFieldRecords(mw); - } - } - - internal ModuleBuilder ModuleBuilder - { - get { return owner.ModuleBuilder; } - } - - ModuleBuilder ITypeOwner.ModuleBuilder - { - get { return owner.ModuleBuilder; } - } - - internal override int GetModuleBuilderToken() - { - return token; - } - - internal bool HasNestedTypes - { - get { return (typeFlags & TypeFlags.HasNestedTypes) != 0; } - } - - // helper for ModuleBuilder.ResolveMethod() - internal MethodBase LookupMethod(int token) - { - foreach (MethodBuilder method in methods) - { - if (method.MetadataToken == token) - { - return method; - } - } - return null; - } - - public bool IsCreated() - { - return (typeFlags & TypeFlags.Baked) != 0; - } - - internal override void CheckBaked() - { - if ((typeFlags & TypeFlags.Baked) == 0) - { - throw new NotSupportedException(); - } - } - - public override Type[] __GetDeclaredTypes() - { - if (this.HasNestedTypes) - { - List types = new List(); - List classes = this.ModuleBuilder.NestedClass.GetNestedClasses(token); - foreach (int nestedClass in classes) - { - types.Add(this.ModuleBuilder.ResolveType(nestedClass)); - } - return types.ToArray(); - } - else - { - return Type.EmptyTypes; - } - } - - public override FieldInfo[] __GetDeclaredFields() - { - return Util.ToArray(fields, Empty.Array); - } - - public override EventInfo[] __GetDeclaredEvents() - { - return Util.ToArray(events, Empty.Array); - } - - public override PropertyInfo[] __GetDeclaredProperties() - { - return Util.ToArray(properties, Empty.Array); - } - - internal override bool IsModulePseudoType - { - get { return token == 0x02000001; } - } - - internal override bool IsBaked - { - get { return IsCreated(); } - } - } - - sealed class BakedType : TypeInfo - { - internal BakedType(TypeBuilder typeBuilder) - : base(typeBuilder) - { - } - - public override string AssemblyQualifiedName - { - get { return underlyingType.AssemblyQualifiedName; } - } - - public override Type BaseType - { - get { return underlyingType.BaseType; } - } - - public override string __Name - { - get { return underlyingType.__Name; } - } - - public override string __Namespace - { - get { return underlyingType.__Namespace; } - } - - public override string Name - { - // we need to escape here, because TypeBuilder.Name does not escape - get { return TypeNameParser.Escape(underlyingType.__Name); } - } - - public override string FullName - { - get { return GetFullName(); } - } - - public override TypeAttributes Attributes - { - get { return underlyingType.Attributes; } - } - - public override Type[] __GetDeclaredInterfaces() - { - return underlyingType.__GetDeclaredInterfaces(); - } - - public override MethodBase[] __GetDeclaredMethods() - { - return underlyingType.__GetDeclaredMethods(); - } - - public override __MethodImplMap __GetMethodImplMap() - { - return underlyingType.__GetMethodImplMap(); - } - - public override FieldInfo[] __GetDeclaredFields() - { - return underlyingType.__GetDeclaredFields(); - } - - public override EventInfo[] __GetDeclaredEvents() - { - return underlyingType.__GetDeclaredEvents(); - } - - public override PropertyInfo[] __GetDeclaredProperties() - { - return underlyingType.__GetDeclaredProperties(); - } - - public override Type[] __GetDeclaredTypes() - { - return underlyingType.__GetDeclaredTypes(); - } - - public override Type DeclaringType - { - get { return underlyingType.DeclaringType; } - } - - public override StructLayoutAttribute StructLayoutAttribute - { - get { return underlyingType.StructLayoutAttribute; } - } - - public override Type[] GetGenericArguments() - { - return underlyingType.GetGenericArguments(); - } - - internal override Type GetGenericTypeArgument(int index) - { - return underlyingType.GetGenericTypeArgument(index); - } - - public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - return underlyingType.__GetGenericArgumentsCustomModifiers(); - } - - public override bool IsGenericType - { - get { return underlyingType.IsGenericType; } - } - - public override bool IsGenericTypeDefinition - { - get { return underlyingType.IsGenericTypeDefinition; } - } - - public override bool ContainsGenericParameters - { - get { return underlyingType.ContainsGenericParameters; } - } - - public override int MetadataToken - { - get { return underlyingType.MetadataToken; } - } - - public override Module Module - { - get { return underlyingType.Module; } - } - - internal override int GetModuleBuilderToken() - { - return underlyingType.GetModuleBuilderToken(); - } - - internal override bool IsBaked - { - get { return true; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Enums.cs b/mcs/class/IKVM.Reflection/Enums.cs deleted file mode 100644 index 2ff8de990bd..00000000000 --- a/mcs/class/IKVM.Reflection/Enums.cs +++ /dev/null @@ -1,324 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection -{ - [Flags] - public enum AssemblyNameFlags - { - None = 0, - PublicKey = 1, - Retargetable = 256, - EnableJITcompileOptimizer = 16384, - EnableJITcompileTracking = 32768, - } - - public enum AssemblyContentType - { - Default = 0, - WindowsRuntime = 1, - } - - [Flags] - public enum BindingFlags - { - Default = 0, - IgnoreCase = 1, - DeclaredOnly = 2, - Instance = 4, - Static = 8, - Public = 16, - NonPublic = 32, - FlattenHierarchy = 64, - } - - [Flags] - public enum CallingConventions - { - Standard = 1, - VarArgs = 2, - Any = 3, - HasThis = 32, - ExplicitThis = 64, - } - - [Flags] - public enum EventAttributes - { - None = 0, - SpecialName = 512, - RTSpecialName = 1024, - ReservedMask = 1024, - } - - [Flags] - public enum FieldAttributes - { - PrivateScope = 0, - Private = 1, - FamANDAssem = 2, - Assembly = 3, - Family = 4, - FamORAssem = 5, - Public = 6, - FieldAccessMask = 7, - Static = 16, - InitOnly = 32, - Literal = 64, - NotSerialized = 128, - HasFieldRVA = 256, - SpecialName = 512, - RTSpecialName = 1024, - HasFieldMarshal = 4096, - PinvokeImpl = 8192, - HasDefault = 32768, - ReservedMask = 38144, - } - - [Flags] - public enum GenericParameterAttributes - { - None = 0, - Covariant = 1, - Contravariant = 2, - VarianceMask = 3, - ReferenceTypeConstraint = 4, - NotNullableValueTypeConstraint = 8, - DefaultConstructorConstraint = 16, - SpecialConstraintMask = 28, - } - - public enum ImageFileMachine - { - I386 = 332, - ARM = 452, - IA64 = 512, - AMD64 = 34404, - } - - [FlagsAttribute] - public enum MemberTypes - { - Constructor = 0x01, - Event = 0x02, - Field = 0x04, - Method = 0x08, - Property = 0x10, - TypeInfo = 0x20, - Custom = 0x40, - NestedType = 0x80, - All = Constructor | Event | Field | Method | Property | TypeInfo | NestedType - } - - [Flags] - public enum MethodAttributes - { - MemberAccessMask = 0x0007, - PrivateScope = 0x0000, - Private = 0x0001, - FamANDAssem = 0x0002, - Assembly = 0x0003, - Family = 0x0004, - FamORAssem = 0x0005, - Public = 0x0006, - Static = 0x0010, - Final = 0x0020, - Virtual = 0x0040, - HideBySig = 0x0080, - VtableLayoutMask = 0x0100, - ReuseSlot = 0x0000, - NewSlot = 0x0100, - CheckAccessOnOverride = 0x0200, - Abstract = 0x0400, - SpecialName = 0x0800, - - PinvokeImpl = 0x2000, - UnmanagedExport = 0x0008, - - RTSpecialName = 0x1000, - HasSecurity = 0x4000, - RequireSecObject = 0x8000, - - ReservedMask = 0xd000, - } - - [Flags] - public enum MethodImplAttributes - { - CodeTypeMask = 0x0003, - IL = 0x0000, - Native = 0x0001, - OPTIL = 0x0002, - Runtime = 0x0003, - ManagedMask = 0x0004, - Unmanaged = 0x0004, - Managed = 0x0000, - - ForwardRef = 0x0010, - PreserveSig = 0x0080, - InternalCall = 0x1000, - Synchronized = 0x0020, - NoInlining = 0x0008, - NoOptimization = 0x0040, - AggressiveInlining = 0x0100, - - MaxMethodImplVal = 0xffff, - } - - [Flags] - public enum ParameterAttributes - { - None = 0, - In = 1, - Out = 2, - Lcid = 4, - Retval = 8, - Optional = 16, - HasDefault = 4096, - HasFieldMarshal = 8192, - Reserved3 = 16384, - Reserved4 = 32768, - ReservedMask = 61440, - } - - [Flags] - public enum PortableExecutableKinds - { - NotAPortableExecutableImage = 0, - ILOnly = 1, - Required32Bit = 2, - PE32Plus = 4, - Unmanaged32Bit = 8, - Preferred32Bit = 16, - } - - public enum ProcessorArchitecture - { - None = 0, - MSIL = 1, - X86 = 2, - IA64 = 3, - Amd64 = 4, - Arm = 5, - // if an item is added here, make sure to update AssemblyName.ProcessorArchitecture and Fusion.ParseAssemblyName as well - } - - [Flags] - public enum PropertyAttributes - { - None = 0, - SpecialName = 512, - RTSpecialName = 1024, - HasDefault = 4096, - } - - [Flags] - public enum ResourceAttributes - { - Public = 1, - Private = 2, - } - - [Flags] - public enum ResourceLocation - { - Embedded = 1, - ContainedInAnotherAssembly = 2, - ContainedInManifestFile = 4, - } - - [Flags] - public enum TypeAttributes - { - AnsiClass = 0, - Class = 0, - AutoLayout = 0, - NotPublic = 0, - Public = 1, - NestedPublic = 2, - NestedPrivate = 3, - NestedFamily = 4, - NestedAssembly = 5, - NestedFamANDAssem = 6, - VisibilityMask = 7, - NestedFamORAssem = 7, - SequentialLayout = 8, - ExplicitLayout = 16, - LayoutMask = 24, - ClassSemanticsMask = 32, - Interface = 32, - Abstract = 128, - Sealed = 256, - SpecialName = 1024, - RTSpecialName = 2048, - Import = 4096, - Serializable = 8192, - WindowsRuntime = 16384, - UnicodeClass = 65536, - AutoClass = 131072, - CustomFormatClass = 196608, - StringFormatMask = 196608, - HasSecurity = 262144, - ReservedMask = 264192, - BeforeFieldInit = 1048576, - CustomFormatMask = 12582912, - } - - // IKVM.Reflection specific type - [Flags] - public enum DllCharacteristics - { - HighEntropyVA = 0x0020, // IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA - DynamicBase = 0x0040, // IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE - NoSEH = 0x0400, // IMAGE_DLLCHARACTERISTICS_NO_SEH - NXCompat = 0x0100, // IMAGE_DLLCHARACTERISTICS_NX_COMPAT - AppContainer = 0x1000, // IMAGE_DLLCHARACTERISTICS_APPCONTAINER - TerminalServerAware = 0x8000, // IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE - } - - // IKVM.Reflection specific type - [Flags] - public enum ImplMapFlags - { - NoMangle = 0x0001, - CharSetMask = 0x0006, - CharSetNotSpec = 0x0000, - CharSetAnsi = 0x0002, - CharSetUnicode = 0x0004, - CharSetAuto = 0x0006, - SupportsLastError = 0x0040, - CallConvMask = 0x0700, - CallConvWinapi = 0x0100, - CallConvCdecl = 0x0200, - CallConvStdcall = 0x0300, - CallConvThiscall = 0x0400, - CallConvFastcall = 0x0500, - // non-standard flags (i.e. CLR specific) - BestFitOn = 0x0010, - BestFitOff = 0x0020, - CharMapErrorOn = 0x1000, - CharMapErrorOff = 0x2000, - } -} diff --git a/mcs/class/IKVM.Reflection/EventInfo.cs b/mcs/class/IKVM.Reflection/EventInfo.cs deleted file mode 100644 index ffd9a0df32d..00000000000 --- a/mcs/class/IKVM.Reflection/EventInfo.cs +++ /dev/null @@ -1,237 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System.Collections.Generic; -using System.Diagnostics; - -namespace IKVM.Reflection -{ - public abstract class EventInfo : MemberInfo - { - // prevent external subclasses - internal EventInfo() - { - } - - public sealed override MemberTypes MemberType - { - get { return MemberTypes.Event; } - } - - public abstract EventAttributes Attributes { get; } - public abstract MethodInfo GetAddMethod(bool nonPublic); - public abstract MethodInfo GetRaiseMethod(bool nonPublic); - public abstract MethodInfo GetRemoveMethod(bool nonPublic); - public abstract MethodInfo[] GetOtherMethods(bool nonPublic); - public abstract MethodInfo[] __GetMethods(); - public abstract Type EventHandlerType { get; } - internal abstract bool IsPublic { get; } - internal abstract bool IsNonPrivate { get; } - internal abstract bool IsStatic { get; } - - public bool IsSpecialName - { - get { return (Attributes & EventAttributes.SpecialName) != 0; } - } - - public MethodInfo GetAddMethod() - { - return GetAddMethod(false); - } - - public MethodInfo GetRaiseMethod() - { - return GetRaiseMethod(false); - } - - public MethodInfo GetRemoveMethod() - { - return GetRemoveMethod(false); - } - - public MethodInfo[] GetOtherMethods() - { - return GetOtherMethods(false); - } - - internal virtual EventInfo BindTypeParameters(Type type) - { - return new GenericEventInfo(this.DeclaringType.BindTypeParameters(type), this); - } - - public override string ToString() - { - return this.DeclaringType.ToString() + " " + Name; - } - - internal sealed override bool BindingFlagsMatch(BindingFlags flags) - { - return BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static, BindingFlags.Instance); - } - - internal sealed override bool BindingFlagsMatchInherited(BindingFlags flags) - { - return IsNonPrivate - && BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance); - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - return new EventInfoWithReflectedType(type, this); - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - // events don't have pseudo custom attributes - return null; - } - } - - sealed class EventInfoWithReflectedType : EventInfo - { - private readonly Type reflectedType; - private readonly EventInfo eventInfo; - - internal EventInfoWithReflectedType(Type reflectedType, EventInfo eventInfo) - { - Debug.Assert(reflectedType != eventInfo.DeclaringType); - this.reflectedType = reflectedType; - this.eventInfo = eventInfo; - } - - public override EventAttributes Attributes - { - get { return eventInfo.Attributes; } - } - - public override MethodInfo GetAddMethod(bool nonPublic) - { - return SetReflectedType(eventInfo.GetAddMethod(nonPublic), reflectedType); - } - - public override MethodInfo GetRaiseMethod(bool nonPublic) - { - return SetReflectedType(eventInfo.GetRaiseMethod(nonPublic), reflectedType); - } - - public override MethodInfo GetRemoveMethod(bool nonPublic) - { - return SetReflectedType(eventInfo.GetRemoveMethod(nonPublic), reflectedType); - } - - public override MethodInfo[] GetOtherMethods(bool nonPublic) - { - return SetReflectedType(eventInfo.GetOtherMethods(nonPublic), reflectedType); - } - - public override MethodInfo[] __GetMethods() - { - return SetReflectedType(eventInfo.__GetMethods(), reflectedType); - } - - public override Type EventHandlerType - { - get { return eventInfo.EventHandlerType; } - } - - internal override bool IsPublic - { - get { return eventInfo.IsPublic; } - } - - internal override bool IsNonPrivate - { - get { return eventInfo.IsNonPrivate; } - } - - internal override bool IsStatic - { - get { return eventInfo.IsStatic; } - } - - internal override EventInfo BindTypeParameters(Type type) - { - return eventInfo.BindTypeParameters(type); - } - - public override string ToString() - { - return eventInfo.ToString(); - } - - public override bool __IsMissing - { - get { return eventInfo.__IsMissing; } - } - - public override Type DeclaringType - { - get { return eventInfo.DeclaringType; } - } - - public override Type ReflectedType - { - get { return reflectedType; } - } - - public override bool Equals(object obj) - { - EventInfoWithReflectedType other = obj as EventInfoWithReflectedType; - return other != null - && other.reflectedType == reflectedType - && other.eventInfo == eventInfo; - } - - public override int GetHashCode() - { - return reflectedType.GetHashCode() ^ eventInfo.GetHashCode(); - } - - public override int MetadataToken - { - get { return eventInfo.MetadataToken; } - } - - public override Module Module - { - get { return eventInfo.Module; } - } - - public override string Name - { - get { return eventInfo.Name; } - } - - internal override bool IsBaked - { - get { return eventInfo.IsBaked; } - } - - internal override int GetCurrentToken() - { - return eventInfo.GetCurrentToken(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/ExceptionHandlingClause.cs b/mcs/class/IKVM.Reflection/ExceptionHandlingClause.cs deleted file mode 100644 index 3553f901a19..00000000000 --- a/mcs/class/IKVM.Reflection/ExceptionHandlingClause.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - [Flags] - public enum ExceptionHandlingClauseOptions - { - Clause = 0x0000, - Filter = 0x0001, - Finally = 0x0002, - Fault = 0x0004, - } - - public sealed class ExceptionHandlingClause - { - private readonly int flags; - private readonly int tryOffset; - private readonly int tryLength; - private readonly int handlerOffset; - private readonly int handlerLength; - private readonly Type catchType; - private readonly int filterOffset; - - internal ExceptionHandlingClause(ModuleReader module, int flags, int tryOffset, int tryLength, int handlerOffset, int handlerLength, int classTokenOrfilterOffset, IGenericContext context) - { - this.flags = flags; - this.tryOffset = tryOffset; - this.tryLength = tryLength; - this.handlerOffset = handlerOffset; - this.handlerLength = handlerLength; - this.catchType = flags == (int)ExceptionHandlingClauseOptions.Clause && classTokenOrfilterOffset != 0 ? module.ResolveType(classTokenOrfilterOffset, context) : null; - this.filterOffset = flags == (int)ExceptionHandlingClauseOptions.Filter ? classTokenOrfilterOffset : 0; - } - - public Type CatchType - { - get { return catchType; } - } - - public int FilterOffset - { - get { return filterOffset; } - } - - public ExceptionHandlingClauseOptions Flags - { - get { return (ExceptionHandlingClauseOptions)flags; } - } - - public int HandlerLength - { - get { return handlerLength; } - } - - public int HandlerOffset - { - get { return handlerOffset; } - } - - public int TryLength - { - get { return tryLength; } - } - - public int TryOffset - { - get { return tryOffset; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/FieldInfo.cs b/mcs/class/IKVM.Reflection/FieldInfo.cs deleted file mode 100644 index 92f89090ea0..00000000000 --- a/mcs/class/IKVM.Reflection/FieldInfo.cs +++ /dev/null @@ -1,304 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace IKVM.Reflection -{ - public abstract class FieldInfo : MemberInfo - { - // prevent external subclasses - internal FieldInfo() - { - } - - public sealed override MemberTypes MemberType - { - get { return MemberTypes.Field; } - } - - public abstract FieldAttributes Attributes { get; } - public abstract void __GetDataFromRVA(byte[] data, int offset, int length); - public abstract int __FieldRVA { get; } - public abstract Object GetRawConstantValue(); - internal abstract FieldSignature FieldSignature { get; } - - public Type FieldType - { - get { return this.FieldSignature.FieldType; } - } - - public CustomModifiers __GetCustomModifiers() - { - return this.FieldSignature.GetCustomModifiers(); - } - - public Type[] GetOptionalCustomModifiers() - { - return __GetCustomModifiers().GetOptional(); - } - - public Type[] GetRequiredCustomModifiers() - { - return __GetCustomModifiers().GetRequired(); - } - - public bool IsStatic - { - get { return (Attributes & FieldAttributes.Static) != 0; } - } - - public bool IsLiteral - { - get { return (Attributes & FieldAttributes.Literal) != 0; } - } - - public bool IsInitOnly - { - get { return (Attributes & FieldAttributes.InitOnly) != 0; } - } - - public bool IsNotSerialized - { - get { return (Attributes & FieldAttributes.NotSerialized) != 0; } - } - - public bool IsSpecialName - { - get { return (Attributes & FieldAttributes.SpecialName) != 0; } - } - - public bool IsPublic - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; } - } - - public bool IsPrivate - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; } - } - - public bool IsFamily - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; } - } - - public bool IsFamilyOrAssembly - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; } - } - - public bool IsAssembly - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; } - } - - public bool IsFamilyAndAssembly - { - get { return (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; } - } - - public bool IsPinvokeImpl - { - get { return (Attributes & FieldAttributes.PinvokeImpl) != 0; } - } - - public virtual FieldInfo __GetFieldOnTypeDefinition() - { - return this; - } - - public abstract bool __TryGetFieldOffset(out int offset); - - public bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - return FieldMarshal.ReadFieldMarshal(this.Module, GetCurrentToken(), out fieldMarshal); - } - - internal abstract int ImportTo(Emit.ModuleBuilder module); - - internal virtual FieldInfo BindTypeParameters(Type type) - { - return new GenericFieldInstance(this.DeclaringType.BindTypeParameters(type), this); - } - - internal sealed override bool BindingFlagsMatch(BindingFlags flags) - { - return BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static, BindingFlags.Instance); - } - - internal sealed override bool BindingFlagsMatchInherited(BindingFlags flags) - { - return (Attributes & FieldAttributes.FieldAccessMask) > FieldAttributes.Private - && BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance); - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - return new FieldInfoWithReflectedType(type, this); - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - Module module = this.Module; - List list = new List(); - if (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_MarshalAsAttribute)) - { - FieldMarshal spec; - if (__TryGetFieldMarshal(out spec)) - { - list.Add(CustomAttributeData.CreateMarshalAsPseudoCustomAttribute(module, spec)); - } - } - if (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_FieldOffsetAttribute)) - { - int offset; - if (__TryGetFieldOffset(out offset)) - { - list.Add(CustomAttributeData.CreateFieldOffsetPseudoCustomAttribute(module, offset)); - } - } - return list; - } - } - - sealed class FieldInfoWithReflectedType : FieldInfo - { - private readonly Type reflectedType; - private readonly FieldInfo field; - - internal FieldInfoWithReflectedType(Type reflectedType, FieldInfo field) - { - Debug.Assert(reflectedType != field.DeclaringType); - this.reflectedType = reflectedType; - this.field = field; - } - - public override FieldAttributes Attributes - { - get { return field.Attributes; } - } - - public override void __GetDataFromRVA(byte[] data, int offset, int length) - { - field.__GetDataFromRVA(data, offset, length); - } - - public override int __FieldRVA - { - get { return field.__FieldRVA; } - } - - public override bool __TryGetFieldOffset(out int offset) - { - return field.__TryGetFieldOffset(out offset); - } - - public override Object GetRawConstantValue() - { - return field.GetRawConstantValue(); - } - - internal override FieldSignature FieldSignature - { - get { return field.FieldSignature; } - } - - public override FieldInfo __GetFieldOnTypeDefinition() - { - return field.__GetFieldOnTypeDefinition(); - } - - internal override int ImportTo(Emit.ModuleBuilder module) - { - return field.ImportTo(module); - } - - internal override FieldInfo BindTypeParameters(Type type) - { - return field.BindTypeParameters(type); - } - - public override bool __IsMissing - { - get { return field.__IsMissing; } - } - - public override Type DeclaringType - { - get { return field.DeclaringType; } - } - - public override Type ReflectedType - { - get { return reflectedType; } - } - - public override bool Equals(object obj) - { - FieldInfoWithReflectedType other = obj as FieldInfoWithReflectedType; - return other != null - && other.reflectedType == reflectedType - && other.field == field; - } - - public override int GetHashCode() - { - return reflectedType.GetHashCode() ^ field.GetHashCode(); - } - - public override int MetadataToken - { - get { return field.MetadataToken; } - } - - public override Module Module - { - get { return field.Module; } - } - - public override string Name - { - get { return field.Name; } - } - - public override string ToString() - { - return field.ToString(); - } - - internal override int GetCurrentToken() - { - return field.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return field.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/FieldSignature.cs b/mcs/class/IKVM.Reflection/FieldSignature.cs deleted file mode 100644 index 481fc615891..00000000000 --- a/mcs/class/IKVM.Reflection/FieldSignature.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - sealed class FieldSignature : Signature - { - private readonly Type fieldType; - private readonly CustomModifiers mods; - - internal static FieldSignature Create(Type fieldType, CustomModifiers customModifiers) - { - return new FieldSignature(fieldType, customModifiers); - } - - private FieldSignature(Type fieldType, CustomModifiers mods) - { - this.fieldType = fieldType; - this.mods = mods; - } - - public override bool Equals(object obj) - { - FieldSignature other = obj as FieldSignature; - return other != null - && other.fieldType.Equals(fieldType) - && other.mods.Equals(mods); - } - - public override int GetHashCode() - { - return fieldType.GetHashCode() ^ mods.GetHashCode(); - } - - internal Type FieldType - { - get { return fieldType; } - } - - internal CustomModifiers GetCustomModifiers() - { - return mods; - } - - internal FieldSignature ExpandTypeParameters(Type declaringType) - { - return new FieldSignature( - fieldType.BindTypeParameters(declaringType), - mods.Bind(declaringType)); - } - - internal static FieldSignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context) - { - if (br.ReadByte() != FIELD) - { - throw new BadImageFormatException(); - } - CustomModifiers mods = CustomModifiers.Read(module, br, context); - Type fieldType = ReadType(module, br, context); - return new FieldSignature(fieldType, mods); - } - - internal override void WriteSig(ModuleBuilder module, ByteBuffer bb) - { - bb.Write(FIELD); - WriteCustomModifiers(module, bb, mods); - WriteType(module, bb, fieldType); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Fusion.cs b/mcs/class/IKVM.Reflection/Fusion.cs deleted file mode 100644 index d9c0e086110..00000000000 --- a/mcs/class/IKVM.Reflection/Fusion.cs +++ /dev/null @@ -1,534 +0,0 @@ -/* - Copyright (C) 2010-2012 Jeroen Frijters - Copyright (C) 2011 Marek Safar - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace IKVM.Reflection -{ - struct ParsedAssemblyName - { - internal string Name; - internal Version Version; - internal string Culture; - internal string PublicKeyToken; - internal bool? Retargetable; - internal ProcessorArchitecture ProcessorArchitecture; - internal bool HasPublicKey; - internal bool WindowsRuntime; - } - - enum ParseAssemblyResult - { - OK, - GenericError, - DuplicateKey, - } - - static class Fusion - { - internal static bool CompareAssemblyIdentityNative(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result) - { - bool equivalent; - Marshal.ThrowExceptionForHR(CompareAssemblyIdentity(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out equivalent, out result)); - return equivalent; - } - - [DllImport("fusion", CharSet = CharSet.Unicode)] - private static extern int CompareAssemblyIdentity(string pwzAssemblyIdentity1, bool fUnified1, string pwzAssemblyIdentity2, bool fUnified2, out bool pfEquivalent, out AssemblyComparisonResult pResult); - - // internal for use by mcs - internal static bool CompareAssemblyIdentityPure(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result) - { - ParsedAssemblyName name1; - ParsedAssemblyName name2; - - ParseAssemblyResult r = ParseAssemblyName(assemblyIdentity1, out name1); - if (r != ParseAssemblyResult.OK || (r = ParseAssemblyName(assemblyIdentity2, out name2)) != ParseAssemblyResult.OK) - { - result = AssemblyComparisonResult.NonEquivalent; - switch (r) - { - case ParseAssemblyResult.DuplicateKey: - throw new System.IO.FileLoadException(); - case ParseAssemblyResult.GenericError: - default: - throw new ArgumentException(); - } - } - - bool partial = IsPartial(name1); - - if ((partial && unified1) || IsPartial(name2)) - { - result = AssemblyComparisonResult.NonEquivalent; - throw new ArgumentException(); - } - if (!name1.Name.Equals(name2.Name, StringComparison.InvariantCultureIgnoreCase)) - { - result = AssemblyComparisonResult.NonEquivalent; - return false; - } - if (name1.Name.Equals("mscorlib", StringComparison.InvariantCultureIgnoreCase)) - { - result = AssemblyComparisonResult.EquivalentFullMatch; - return true; - } - if (partial && name1.Culture == null) - { - } - else if (!name1.Culture.Equals(name2.Culture, StringComparison.InvariantCultureIgnoreCase)) - { - result = AssemblyComparisonResult.NonEquivalent; - return false; - } - if (IsStrongNamed(name2)) - { - if (partial && name1.PublicKeyToken == null) - { - } - else if (name1.PublicKeyToken != name2.PublicKeyToken) - { - result = AssemblyComparisonResult.NonEquivalent; - return false; - } - if (partial && name1.Version == null) - { - result = AssemblyComparisonResult.EquivalentPartialMatch; - return true; - } - else if (IsFrameworkAssembly(name2)) - { - result = partial ? AssemblyComparisonResult.EquivalentPartialFXUnified : AssemblyComparisonResult.EquivalentFXUnified; - return true; - } - else if (name1.Version.Revision == -1 || name2.Version.Revision == -1) - { - result = AssemblyComparisonResult.NonEquivalent; - throw new ArgumentException(); - } - else if (name1.Version < name2.Version) - { - if (unified2) - { - result = partial ? AssemblyComparisonResult.EquivalentPartialUnified : AssemblyComparisonResult.EquivalentUnified; - return true; - } - else - { - result = partial ? AssemblyComparisonResult.NonEquivalentPartialVersion : AssemblyComparisonResult.NonEquivalentVersion; - return false; - } - } - else if (name1.Version > name2.Version) - { - if (unified1) - { - result = partial ? AssemblyComparisonResult.EquivalentPartialUnified : AssemblyComparisonResult.EquivalentUnified; - return true; - } - else - { - result = partial ? AssemblyComparisonResult.NonEquivalentPartialVersion : AssemblyComparisonResult.NonEquivalentVersion; - return false; - } - } - else - { - result = partial ? AssemblyComparisonResult.EquivalentPartialMatch : AssemblyComparisonResult.EquivalentFullMatch; - return true; - } - } - else if (IsStrongNamed(name1)) - { - result = AssemblyComparisonResult.NonEquivalent; - return false; - } - else - { - result = partial ? AssemblyComparisonResult.EquivalentPartialWeakNamed : AssemblyComparisonResult.EquivalentWeakNamed; - return true; - } - } - - static bool IsFrameworkAssembly(ParsedAssemblyName name) - { - // A list of FX assemblies which require some form of remapping - // When 4.0 + 1 version is release, assemblies introduced in v4.0 - // will have to be added - switch (name.Name) - { - case "System": - case "System.Core": - case "System.Data": - case "System.Data.DataSetExtensions": - case "System.Data.Linq": - case "System.Data.OracleClient": - case "System.Data.Services": - case "System.Data.Services.Client": - case "System.IdentityModel": - case "System.IdentityModel.Selectors": - case "System.Runtime.Remoting": - case "System.Runtime.Serialization": - case "System.ServiceModel": - case "System.Transactions": - case "System.Windows.Forms": - case "System.Xml": - case "System.Xml.Linq": - return name.PublicKeyToken == "b77a5c561934e089"; - - case "System.Configuration": - case "System.Configuration.Install": - case "System.Design": - case "System.DirectoryServices": - case "System.Drawing": - case "System.Drawing.Design": - case "System.EnterpriseServices": - case "System.Management": - case "System.Messaging": - case "System.Runtime.Serialization.Formatters.Soap": - case "System.Security": - case "System.ServiceProcess": - case "System.Web": - case "System.Web.Mobile": - case "System.Web.Services": - return name.PublicKeyToken == "b03f5f7f11d50a3a"; - - case "System.ComponentModel.DataAnnotations": - case "System.ServiceModel.Web": - case "System.Web.Abstractions": - case "System.Web.Extensions": - case "System.Web.Extensions.Design": - case "System.Web.DynamicData": - case "System.Web.Routing": - return name.PublicKeyToken == "31bf3856ad364e35"; - } - - return false; - } - - internal static ParseAssemblyResult ParseAssemblySimpleName(string fullName, out int pos, out string simpleName) - { - StringBuilder sb = new StringBuilder(); - pos = 0; - simpleName = null; - while (pos < fullName.Length && char.IsWhiteSpace(fullName[pos])) - { - pos++; - } - char quoteOrComma = ','; - if (pos < fullName.Length && (fullName[pos] == '\"' || fullName[pos] == '\'')) - { - quoteOrComma = fullName[pos++]; - } - while (pos < fullName.Length) - { - char ch = fullName[pos++]; - if (ch == '\\') - { - if (pos == fullName.Length) - { - return ParseAssemblyResult.GenericError; - } - ch = fullName[pos++]; - if (ch == '\\') - { - return ParseAssemblyResult.GenericError; - } - } - else if (ch == quoteOrComma) - { - if (ch != ',') - { - while (pos != fullName.Length) - { - ch = fullName[pos++]; - if (ch == ',') - { - break; - } - if (!char.IsWhiteSpace(ch)) - { - return ParseAssemblyResult.GenericError; - } - } - } - break; - } - else if (ch == '=' || (quoteOrComma == ',' && (ch == '\'' || ch == '"'))) - { - return ParseAssemblyResult.GenericError; - } - sb.Append(ch); - } - simpleName = sb.ToString().Trim(); - if (simpleName.Length == 0) - { - return ParseAssemblyResult.GenericError; - } - if (pos == fullName.Length && fullName[fullName.Length - 1] == ',') - { - return ParseAssemblyResult.GenericError; - } - return ParseAssemblyResult.OK; - } - - internal static ParseAssemblyResult ParseAssemblyName(string fullName, out ParsedAssemblyName parsedName) - { - parsedName = new ParsedAssemblyName(); - int pos; - ParseAssemblyResult res = ParseAssemblySimpleName(fullName, out pos, out parsedName.Name); - if (res != ParseAssemblyResult.OK || pos == fullName.Length) - { - return res; - } - else - { - System.Collections.Generic.Dictionary unknownAttributes = null; - bool hasProcessorArchitecture = false; - bool hasContentType = false; - string[] parts = fullName.Substring(pos).Split(','); - for (int i = 0; i < parts.Length; i++) - { - string[] kv = parts[i].Split('='); - if (kv.Length != 2) - { - return ParseAssemblyResult.GenericError; - } - switch (kv[0].Trim().ToLowerInvariant()) - { - case "version": - if (parsedName.Version != null) - { - return ParseAssemblyResult.DuplicateKey; - } - if (!ParseVersion(kv[1].Trim(), out parsedName.Version)) - { - return ParseAssemblyResult.GenericError; - } - break; - case "culture": - if (parsedName.Culture != null) - { - return ParseAssemblyResult.DuplicateKey; - } - if (!ParseCulture(kv[1].Trim(), out parsedName.Culture)) - { - return ParseAssemblyResult.GenericError; - } - break; - case "publickeytoken": - if (parsedName.PublicKeyToken != null) - { - return ParseAssemblyResult.DuplicateKey; - } - if (!ParsePublicKeyToken(kv[1].Trim(), out parsedName.PublicKeyToken)) - { - return ParseAssemblyResult.GenericError; - } - break; - case "publickey": - if (parsedName.PublicKeyToken != null) - { - return ParseAssemblyResult.DuplicateKey; - } - if (!ParsePublicKey(kv[1].Trim(), out parsedName.PublicKeyToken)) - { - return ParseAssemblyResult.GenericError; - } - parsedName.HasPublicKey = true; - break; - case "retargetable": - if (parsedName.Retargetable.HasValue) - { - return ParseAssemblyResult.DuplicateKey; - } - switch (kv[1].Trim().ToLowerInvariant()) - { - case "yes": - parsedName.Retargetable = true; - break; - case "no": - parsedName.Retargetable = false; - break; - default: - return ParseAssemblyResult.GenericError; - } - break; - case "processorarchitecture": - if (hasProcessorArchitecture) - { - return ParseAssemblyResult.DuplicateKey; - } - hasProcessorArchitecture = true; - switch (kv[1].Trim().ToLowerInvariant()) - { - case "none": - parsedName.ProcessorArchitecture = ProcessorArchitecture.None; - break; - case "msil": - parsedName.ProcessorArchitecture = ProcessorArchitecture.MSIL; - break; - case "x86": - parsedName.ProcessorArchitecture = ProcessorArchitecture.X86; - break; - case "ia64": - parsedName.ProcessorArchitecture = ProcessorArchitecture.IA64; - break; - case "amd64": - parsedName.ProcessorArchitecture = ProcessorArchitecture.Amd64; - break; - case "arm": - parsedName.ProcessorArchitecture = ProcessorArchitecture.Arm; - break; - default: - return ParseAssemblyResult.GenericError; - } - break; - case "contenttype": - if (hasContentType) - { - return ParseAssemblyResult.DuplicateKey; - } - hasContentType = true; - if (kv[1].Trim().ToLowerInvariant() != "windowsruntime") - { - return ParseAssemblyResult.GenericError; - } - parsedName.WindowsRuntime = true; - break; - default: - if (kv[1].Trim() == "") - { - return ParseAssemblyResult.GenericError; - } - if (unknownAttributes == null) - { - unknownAttributes = new System.Collections.Generic.Dictionary(); - } - if (unknownAttributes.ContainsKey(kv[0].Trim().ToLowerInvariant())) - { - return ParseAssemblyResult.DuplicateKey; - } - unknownAttributes.Add(kv[0].Trim().ToLowerInvariant(), null); - break; - } - } - } - return ParseAssemblyResult.OK; - } - - private static bool ParseVersion(string str, out Version version) - { - string[] parts = str.Split('.'); - if (parts.Length < 2 || parts.Length > 4) - { - version = null; - ushort dummy; - // if the version consists of a single integer, it is invalid, but not invalid enough to fail the parse of the whole assembly name - return parts.Length == 1 && ushort.TryParse(parts[0], System.Globalization.NumberStyles.Integer, null, out dummy); - } - if (parts[0] == "" || parts[1] == "") - { - // this is a strange scenario, the version is invalid, but not invalid enough to fail the parse of the whole assembly name - version = null; - return true; - } - ushort major, minor, build = 65535, revision = 65535; - if (ushort.TryParse(parts[0], System.Globalization.NumberStyles.Integer, null, out major) - && ushort.TryParse(parts[1], System.Globalization.NumberStyles.Integer, null, out minor) - && (parts.Length <= 2 || parts[2] == "" || ushort.TryParse(parts[2], System.Globalization.NumberStyles.Integer, null, out build)) - && (parts.Length <= 3 || parts[3] == "" || (parts[2] != "" && ushort.TryParse(parts[3], System.Globalization.NumberStyles.Integer, null, out revision)))) - { - if (parts.Length == 4 && parts[3] != "" && parts[2] != "") - { - version = new Version(major, minor, build, revision); - } - else if (parts.Length == 3 && parts[2] != "") - { - version = new Version(major, minor, build); - } - else - { - version = new Version(major, minor); - } - return true; - } - version = null; - return false; - } - - private static bool ParseCulture(string str, out string culture) - { - if (str == null) - { - culture = null; - return false; - } - culture = str; - return true; - } - - private static bool ParsePublicKeyToken(string str, out string publicKeyToken) - { - if (str == null) - { - publicKeyToken = null; - return false; - } - publicKeyToken = str.ToLowerInvariant(); - return true; - } - - private static bool ParsePublicKey(string str, out string publicKeyToken) - { - if (str == null) - { - publicKeyToken = null; - return false; - } - // HACK use AssemblyName to convert PublicKey to PublicKeyToken - byte[] token = new System.Reflection.AssemblyName("Foo, PublicKey=" + str).GetPublicKeyToken(); - StringBuilder sb = new StringBuilder(token.Length * 2); - for (int i = 0; i < token.Length; i++) - { - sb.AppendFormat("{0:x2}", token[i]); - } - publicKeyToken = sb.ToString(); - return true; - } - - private static bool IsPartial(ParsedAssemblyName name) - { - return name.Version == null || name.Culture == null || name.PublicKeyToken == null; - } - - private static bool IsStrongNamed(ParsedAssemblyName name) - { - return name.PublicKeyToken != null && name.PublicKeyToken != "null"; - } - } -} diff --git a/mcs/class/IKVM.Reflection/GenericWrappers.cs b/mcs/class/IKVM.Reflection/GenericWrappers.cs deleted file mode 100644 index 1122ff29c4a..00000000000 --- a/mcs/class/IKVM.Reflection/GenericWrappers.cs +++ /dev/null @@ -1,694 +0,0 @@ -/* - Copyright (C) 2009, 2010 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ - // this represents both generic method instantiations and non-generic methods on generic type instantations - // (this means that it can be a generic method declaration as well as a generic method instance) - sealed class GenericMethodInstance : MethodInfo - { - private readonly Type declaringType; - private readonly MethodInfo method; - private readonly Type[] methodArgs; - private MethodSignature lazyMethodSignature; - - internal GenericMethodInstance(Type declaringType, MethodInfo method, Type[] methodArgs) - { - System.Diagnostics.Debug.Assert(!(method is GenericMethodInstance)); - this.declaringType = declaringType; - this.method = method; - this.methodArgs = methodArgs; - } - - public override bool Equals(object obj) - { - GenericMethodInstance other = obj as GenericMethodInstance; - return other != null - && other.method.Equals(method) - && other.declaringType.Equals(declaringType) - && Util.ArrayEquals(other.methodArgs, methodArgs); - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() * 33 ^ method.GetHashCode() ^ Util.GetHashCode(methodArgs); - } - - public override Type ReturnType - { - get { return method.ReturnType.BindTypeParameters(this); } - } - - public override ParameterInfo ReturnParameter - { - get { return new GenericParameterInfoImpl(this, method.ReturnParameter); } - } - - public override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new GenericParameterInfoImpl(this, parameters[i]); - } - return parameters; - } - - internal override int ParameterCount - { - get { return method.ParameterCount; } - } - - public override CallingConventions CallingConvention - { - get { return method.CallingConvention; } - } - - public override MethodAttributes Attributes - { - get { return method.Attributes; } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return method.GetMethodImplementationFlags(); - } - - public override string Name - { - get { return method.Name; } - } - - public override Type DeclaringType - { - get { return declaringType.IsModulePseudoType ? null : declaringType; } - } - - public override Module Module - { - get { return method.Module; } - } - - public override int MetadataToken - { - get { return method.MetadataToken; } - } - - public override MethodBody GetMethodBody() - { - IKVM.Reflection.Reader.MethodDefImpl md = method as IKVM.Reflection.Reader.MethodDefImpl; - if (md != null) - { - return md.GetMethodBody(this); - } - throw new NotSupportedException(); - } - - public override int __MethodRVA - { - get { return method.__MethodRVA; } - } - - public override MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - return new GenericMethodInstance(declaringType, method, typeArguments); - } - - public override bool IsGenericMethod - { - get { return method.IsGenericMethod; } - } - - public override bool IsGenericMethodDefinition - { - get { return method.IsGenericMethodDefinition && methodArgs == null; } - } - - public override bool ContainsGenericParameters - { - get - { - if (declaringType.ContainsGenericParameters) - { - return true; - } - if (methodArgs != null) - { - foreach (Type type in methodArgs) - { - if (type.ContainsGenericParameters) - { - return true; - } - } - } - return false; - } - } - - public override MethodInfo GetGenericMethodDefinition() - { - if (this.IsGenericMethod) - { - if (this.IsGenericMethodDefinition) - { - return this; - } - else if (declaringType.IsConstructedGenericType) - { - return new GenericMethodInstance(declaringType, method, null); - } - else - { - return method; - } - } - throw new InvalidOperationException(); - } - - public override MethodBase __GetMethodOnTypeDefinition() - { - return method; - } - - public override Type[] GetGenericArguments() - { - if (methodArgs == null) - { - return method.GetGenericArguments(); - } - else - { - return (Type[])methodArgs.Clone(); - } - } - - internal override Type GetGenericMethodArgument(int index) - { - if (methodArgs == null) - { - return method.GetGenericMethodArgument(index); - } - else - { - return methodArgs[index]; - } - } - - internal override int GetGenericMethodArgumentCount() - { - return method.GetGenericMethodArgumentCount(); - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return method.GetMethodOnTypeDefinition(); - } - - internal override int ImportTo(Emit.ModuleBuilder module) - { - if (methodArgs == null) - { - return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature); - } - else - { - return module.ImportMethodSpec(declaringType, method, methodArgs); - } - } - - internal override MethodSignature MethodSignature - { - get { return lazyMethodSignature ?? (lazyMethodSignature = method.MethodSignature.Bind(declaringType, methodArgs)); } - } - - internal override MethodBase BindTypeParameters(Type type) - { - System.Diagnostics.Debug.Assert(methodArgs == null); - return new GenericMethodInstance(declaringType.BindTypeParameters(type), method, null); - } - - internal override bool HasThis - { - get { return method.HasThis; } - } - - public override MethodInfo[] __GetMethodImpls() - { - MethodInfo[] methods = method.__GetMethodImpls(); - for (int i = 0; i < methods.Length; i++) - { - methods[i] = (MethodInfo)methods[i].BindTypeParameters(declaringType); - } - return methods; - } - - internal override int GetCurrentToken() - { - return method.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return method.IsBaked; } - } - } - - sealed class GenericFieldInstance : FieldInfo - { - private readonly Type declaringType; - private readonly FieldInfo field; - - internal GenericFieldInstance(Type declaringType, FieldInfo field) - { - this.declaringType = declaringType; - this.field = field; - } - - public override bool Equals(object obj) - { - GenericFieldInstance other = obj as GenericFieldInstance; - return other != null && other.declaringType.Equals(declaringType) && other.field.Equals(field); - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() * 3 ^ field.GetHashCode(); - } - - public override FieldAttributes Attributes - { - get { return field.Attributes; } - } - - public override string Name - { - get { return field.Name; } - } - - public override Type DeclaringType - { - get { return declaringType; } - } - - public override Module Module - { - get { return declaringType.Module; } - } - - public override int MetadataToken - { - get { return field.MetadataToken; } - } - - public override object GetRawConstantValue() - { - return field.GetRawConstantValue(); - } - - public override void __GetDataFromRVA(byte[] data, int offset, int length) - { - field.__GetDataFromRVA(data, offset, length); - } - - public override int __FieldRVA - { - get { return field.__FieldRVA; } - } - - public override bool __TryGetFieldOffset(out int offset) - { - return field.__TryGetFieldOffset(out offset); - } - - public override FieldInfo __GetFieldOnTypeDefinition() - { - return field; - } - - internal override FieldSignature FieldSignature - { - get { return field.FieldSignature.ExpandTypeParameters(declaringType); } - } - - internal override int ImportTo(Emit.ModuleBuilder module) - { - return module.ImportMethodOrField(declaringType, field.Name, field.FieldSignature); - } - - internal override FieldInfo BindTypeParameters(Type type) - { - return new GenericFieldInstance(declaringType.BindTypeParameters(type), field); - } - - internal override int GetCurrentToken() - { - return field.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return field.IsBaked; } - } - } - - sealed class GenericParameterInfoImpl : ParameterInfo - { - private readonly GenericMethodInstance method; - private readonly ParameterInfo parameterInfo; - - internal GenericParameterInfoImpl(GenericMethodInstance method, ParameterInfo parameterInfo) - { - this.method = method; - this.parameterInfo = parameterInfo; - } - - public override string Name - { - get { return parameterInfo.Name; } - } - - public override Type ParameterType - { - get { return parameterInfo.ParameterType.BindTypeParameters(method); } - } - - public override ParameterAttributes Attributes - { - get { return parameterInfo.Attributes; } - } - - public override int Position - { - get { return parameterInfo.Position; } - } - - public override object RawDefaultValue - { - get { return parameterInfo.RawDefaultValue; } - } - - public override CustomModifiers __GetCustomModifiers() - { - return parameterInfo.__GetCustomModifiers().Bind(method); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - return parameterInfo.__TryGetFieldMarshal(out fieldMarshal); - } - - public override MemberInfo Member - { - get { return method; } - } - - public override int MetadataToken - { - get { return parameterInfo.MetadataToken; } - } - - internal override Module Module - { - get { return method.Module; } - } - } - - sealed class GenericPropertyInfo : PropertyInfo - { - private readonly Type typeInstance; - private readonly PropertyInfo property; - - internal GenericPropertyInfo(Type typeInstance, PropertyInfo property) - { - this.typeInstance = typeInstance; - this.property = property; - } - - public override bool Equals(object obj) - { - GenericPropertyInfo other = obj as GenericPropertyInfo; - return other != null && other.typeInstance == typeInstance && other.property == property; - } - - public override int GetHashCode() - { - return typeInstance.GetHashCode() * 537 + property.GetHashCode(); - } - - public override PropertyAttributes Attributes - { - get { return property.Attributes; } - } - - public override bool CanRead - { - get { return property.CanRead; } - } - - public override bool CanWrite - { - get { return property.CanWrite; } - } - - private MethodInfo Wrap(MethodInfo method) - { - if (method == null) - { - return null; - } - return new GenericMethodInstance(typeInstance, method, null); - } - - public override MethodInfo GetGetMethod(bool nonPublic) - { - return Wrap(property.GetGetMethod(nonPublic)); - } - - public override MethodInfo GetSetMethod(bool nonPublic) - { - return Wrap(property.GetSetMethod(nonPublic)); - } - - public override MethodInfo[] GetAccessors(bool nonPublic) - { - MethodInfo[] accessors = property.GetAccessors(nonPublic); - for (int i = 0; i < accessors.Length; i++) - { - accessors[i] = Wrap(accessors[i]); - } - return accessors; - } - - public override object GetRawConstantValue() - { - return property.GetRawConstantValue(); - } - - internal override bool IsPublic - { - get { return property.IsPublic; } - } - - internal override bool IsNonPrivate - { - get { return property.IsNonPrivate; } - } - - internal override bool IsStatic - { - get { return property.IsStatic; } - } - - internal override PropertySignature PropertySignature - { - get { return property.PropertySignature.ExpandTypeParameters(typeInstance); } - } - - public override string Name - { - get { return property.Name; } - } - - public override Type DeclaringType - { - get { return typeInstance; } - } - - public override Module Module - { - get { return typeInstance.Module; } - } - - public override int MetadataToken - { - get { return property.MetadataToken; } - } - - internal override PropertyInfo BindTypeParameters(Type type) - { - return new GenericPropertyInfo(typeInstance.BindTypeParameters(type), property); - } - - internal override bool IsBaked - { - get { return property.IsBaked; } - } - - internal override int GetCurrentToken() - { - return property.GetCurrentToken(); - } - } - - sealed class GenericEventInfo : EventInfo - { - private readonly Type typeInstance; - private readonly EventInfo eventInfo; - - internal GenericEventInfo(Type typeInstance, EventInfo eventInfo) - { - this.typeInstance = typeInstance; - this.eventInfo = eventInfo; - } - - public override bool Equals(object obj) - { - GenericEventInfo other = obj as GenericEventInfo; - return other != null && other.typeInstance == typeInstance && other.eventInfo == eventInfo; - } - - public override int GetHashCode() - { - return typeInstance.GetHashCode() * 777 + eventInfo.GetHashCode(); - } - - public override EventAttributes Attributes - { - get { return eventInfo.Attributes; } - } - - private MethodInfo Wrap(MethodInfo method) - { - if (method == null) - { - return null; - } - return new GenericMethodInstance(typeInstance, method, null); - } - - public override MethodInfo GetAddMethod(bool nonPublic) - { - return Wrap(eventInfo.GetAddMethod(nonPublic)); - } - - public override MethodInfo GetRaiseMethod(bool nonPublic) - { - return Wrap(eventInfo.GetRaiseMethod(nonPublic)); - } - - public override MethodInfo GetRemoveMethod(bool nonPublic) - { - return Wrap(eventInfo.GetRemoveMethod(nonPublic)); - } - - public override MethodInfo[] GetOtherMethods(bool nonPublic) - { - MethodInfo[] others = eventInfo.GetOtherMethods(nonPublic); - for (int i = 0; i < others.Length; i++) - { - others[i] = Wrap(others[i]); - } - return others; - } - - public override MethodInfo[] __GetMethods() - { - MethodInfo[] others = eventInfo.__GetMethods(); - for (int i = 0; i < others.Length; i++) - { - others[i] = Wrap(others[i]); - } - return others; - } - - public override Type EventHandlerType - { - get { return eventInfo.EventHandlerType.BindTypeParameters(typeInstance); } - } - - public override string Name - { - get { return eventInfo.Name; } - } - - public override Type DeclaringType - { - get { return typeInstance; } - } - - public override Module Module - { - get { return eventInfo.Module; } - } - - public override int MetadataToken - { - get { return eventInfo.MetadataToken; } - } - - internal override EventInfo BindTypeParameters(Type type) - { - return new GenericEventInfo(typeInstance.BindTypeParameters(type), eventInfo); - } - - internal override bool IsPublic - { - get { return eventInfo.IsPublic; } - } - - internal override bool IsNonPrivate - { - get { return eventInfo.IsNonPrivate; } - } - - internal override bool IsStatic - { - get { return eventInfo.IsStatic; } - } - - internal override bool IsBaked - { - get { return eventInfo.IsBaked; } - } - - internal override int GetCurrentToken() - { - return eventInfo.GetCurrentToken(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj b/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj deleted file mode 100644 index e7e7ad30cf2..00000000000 --- a/mcs/class/IKVM.Reflection/IKVM.Reflection.csproj +++ /dev/null @@ -1,142 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {4CB170EF-DFE6-4A56-9E1B-A85449E827A7} - Library - Properties - IKVM.Reflection - IKVM.Reflection - v2.0 - 512 - - - - - - - - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mcs/class/IKVM.Reflection/Impl/ITypeOwner.cs b/mcs/class/IKVM.Reflection/Impl/ITypeOwner.cs deleted file mode 100644 index 10050f703d9..00000000000 --- a/mcs/class/IKVM.Reflection/Impl/ITypeOwner.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection.Impl -{ - interface ITypeOwner - { - ModuleBuilder ModuleBuilder { get; } - } -} diff --git a/mcs/class/IKVM.Reflection/Impl/MdbWriter.cs b/mcs/class/IKVM.Reflection/Impl/MdbWriter.cs deleted file mode 100644 index 226137b9389..00000000000 --- a/mcs/class/IKVM.Reflection/Impl/MdbWriter.cs +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -#if MONO -using System; -using System.Collections.Generic; -using Mono.CompilerServices.SymbolWriter; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection.Impl -{ - sealed class Method : IMethodDef - { - internal int token; - internal string name; - internal SymbolDocumentWriter document; - internal int[] offsets; - internal int[] lines; - internal int[] columns; - internal List variables = new List(); - - public string Name - { - get { return name; } - } - - public int Token - { - get { return token; } - } - } - - sealed class SymbolDocumentWriter : System.Diagnostics.SymbolStore.ISymbolDocumentWriter - { - internal readonly string url; - internal SourceFileEntry source; - - internal SymbolDocumentWriter(string url) - { - this.url = url; - } - - public void SetCheckSum(Guid algorithmId, byte[] checkSum) - { - } - - public void SetSource(byte[] source) - { - } - } - - sealed class MdbWriter : ISymbolWriterImpl - { - private readonly ModuleBuilder moduleBuilder; - private readonly Dictionary methods = new Dictionary(); - private readonly Dictionary documents = new Dictionary(); - private Method currentMethod; - - internal MdbWriter(ModuleBuilder moduleBuilder) - { - this.moduleBuilder = moduleBuilder; - } - - public byte[] GetDebugInfo(ref IMAGE_DEBUG_DIRECTORY idd) - { - return Empty.Array; - } - - public void RemapToken(int oldToken, int newToken) - { - if (methods.ContainsKey(oldToken)) - { - methods[oldToken].token = newToken; - } - } - - public void Close() - { - MonoSymbolWriter writer = new MonoSymbolWriter(moduleBuilder.FullyQualifiedName); - - foreach (Method method in methods.Values) - { - if (method.document != null) - { - if (method.document.source == null) - { - method.document.source = new SourceFileEntry(writer.SymbolFile, method.document.url); - } - ICompileUnit file = new CompileUnitEntry(writer.SymbolFile, method.document.source); - SourceMethodBuilder smb = writer.OpenMethod(file, 0, method); - for (int i = 0; i < method.offsets.Length; i++) - { - smb.MarkSequencePoint(method.offsets[i], method.document.source, method.lines[i], method.columns[i], false); - } - for (int i = 0; i < method.variables.Count; i++) - { - writer.DefineLocalVariable(i, method.variables[i]); - } - writer.CloseMethod(); - } - } - - writer.WriteSymbolFile(moduleBuilder.ModuleVersionId); - } - - public System.Diagnostics.SymbolStore.ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) - { - SymbolDocumentWriter writer; - if (!documents.TryGetValue(url, out writer)) - { - writer = new SymbolDocumentWriter(url); - documents.Add(url, writer); - } - return writer; - } - - public void OpenMethod(System.Diagnostics.SymbolStore.SymbolToken method) - { - throw new NotImplementedException(); - } - - public void OpenMethod(System.Diagnostics.SymbolStore.SymbolToken token, MethodBase mb) - { - Method method = new Method(); - method.token = token.GetToken(); - method.name = mb.Name; - methods.Add(token.GetToken(), method); - currentMethod = method; - } - - public void CloseMethod() - { - currentMethod = null; - } - - public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, System.Diagnostics.SymbolStore.SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) - { - } - - public void DefineLocalVariable2(string name, FieldAttributes attributes, int signature, System.Diagnostics.SymbolStore.SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) - { - currentMethod.variables.Add(name); - } - - public void DefineSequencePoints(System.Diagnostics.SymbolStore.ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) - { - currentMethod.document = (SymbolDocumentWriter)document; - currentMethod.offsets = offsets; - currentMethod.lines = lines; - currentMethod.columns = columns; - } - - public void DefineParameter(string name, System.Reflection.ParameterAttributes attributes, int sequence, System.Diagnostics.SymbolStore.SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - } - - public void DefineField(System.Diagnostics.SymbolStore.SymbolToken parent, string name, System.Reflection.FieldAttributes attributes, byte[] signature, System.Diagnostics.SymbolStore.SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - } - - public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, System.Diagnostics.SymbolStore.SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - } - - public void OpenNamespace(string name) - { - } - - public void CloseNamespace() - { - } - - public void UsingNamespace(string fullName) - { - } - - public int OpenScope(int startOffset) - { - return 0; - } - - public void CloseScope(int endOffset) - { - } - - public void SetMethodSourceRange(System.Diagnostics.SymbolStore.ISymbolDocumentWriter startDoc, int startLine, int startColumn, System.Diagnostics.SymbolStore.ISymbolDocumentWriter endDoc, int endLine, int endColumn) - { - } - - public void SetScopeRange(int scopeID, int startOffset, int endOffset) - { - } - - public void SetSymAttribute(System.Diagnostics.SymbolStore.SymbolToken parent, string name, byte[] data) - { - } - - public void SetUserEntryPoint(System.Diagnostics.SymbolStore.SymbolToken entryMethod) - { - } - - public void SetUnderlyingWriter(IntPtr underlyingWriter) - { - throw new InvalidOperationException(); - } - - public void Initialize(IntPtr emitter, string filename, bool fFullBuild) - { - throw new InvalidOperationException(); - } - } -} -#endif // MONO diff --git a/mcs/class/IKVM.Reflection/Impl/PdbWriter.cs b/mcs/class/IKVM.Reflection/Impl/PdbWriter.cs deleted file mode 100644 index b8976bbf323..00000000000 --- a/mcs/class/IKVM.Reflection/Impl/PdbWriter.cs +++ /dev/null @@ -1,1188 +0,0 @@ -/* - Copyright (C) 2008-2010 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Diagnostics.SymbolStore; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection.Impl -{ - [Guid("7dac8207-d3ae-4c75-9b67-92801a497d44")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - interface IMetaDataImport - { - void PlaceHolder_CloseEnum(); - void PlaceHolder_CountEnum(); - void PlaceHolder_ResetEnum(); - void PlaceHolder_EnumTypeDefs(); - void PlaceHolder_EnumInterfaceImpls(); - void PlaceHolder_EnumTypeRefs(); - void PlaceHolder_FindTypeDefByName(); - void PlaceHolder_GetScopeProps(); - void PlaceHolder_GetModuleFromScope(); - - void GetTypeDefProps( - int td, // [IN] TypeDef token for inquiry. - IntPtr szTypeDef, // [OUT] Put name here. - int cchTypeDef, // [IN] size of name buffer in wide chars. - IntPtr pchTypeDef, // [OUT] put size of name (wide chars) here. - IntPtr pdwTypeDefFlags, // [OUT] Put flags here. - IntPtr ptkExtends); // [OUT] Put base class TypeDef/TypeRef here. - - void PlaceHolder_GetInterfaceImplProps(); - void PlaceHolder_GetTypeRefProps(); - void PlaceHolder_ResolveTypeRef(); - void PlaceHolder_EnumMembers(); - void PlaceHolder_EnumMembersWithName(); - void PlaceHolder_EnumMethods(); - void PlaceHolder_EnumMethodsWithName(); - void PlaceHolder_EnumFields(); - void PlaceHolder_EnumFieldsWithName(); - void PlaceHolder_EnumParams(); - void PlaceHolder_EnumMemberRefs(); - void PlaceHolder_EnumMethodImpls(); - void PlaceHolder_EnumPermissionSets(); - void PlaceHolder_FindMember(); - void PlaceHolder_FindMethod(); - void PlaceHolder_FindField(); - void PlaceHolder_FindMemberRef(); - - void GetMethodProps( - int mb, // The method for which to get props. - IntPtr pClass, // Put method's class here. - IntPtr szMethod, // Put method's name here. - int cchMethod, // Size of szMethod buffer in wide chars. - IntPtr pchMethod, // Put actual size here - IntPtr pdwAttr, // Put flags here. - IntPtr ppvSigBlob, // [OUT] point to the blob value of meta data - IntPtr pcbSigBlob, // [OUT] actual size of signature blob - IntPtr pulCodeRVA, // [OUT] codeRVA - IntPtr pdwImplFlags); // [OUT] Impl. Flags - - void PlaceHolder_GetMemberRefProps(); - void PlaceHolder_EnumProperties(); - void PlaceHolder_EnumEvents(); - void PlaceHolder_GetEventProps(); - void PlaceHolder_EnumMethodSemantics(); - void PlaceHolder_GetMethodSemantics(); - void PlaceHolder_GetClassLayout(); - void PlaceHolder_GetFieldMarshal(); - void PlaceHolder_GetRVA(); - void PlaceHolder_GetPermissionSetProps(); - void PlaceHolder_GetSigFromToken(); - void PlaceHolder_GetModuleRefProps(); - void PlaceHolder_EnumModuleRefs(); - void PlaceHolder_GetTypeSpecFromToken(); - void PlaceHolder_GetNameFromToken(); - void PlaceHolder_EnumUnresolvedMethods(); - void PlaceHolder_GetUserString(); - void PlaceHolder_GetPinvokeMap(); - void PlaceHolder_EnumSignatures(); - void PlaceHolder_EnumTypeSpecs(); - void PlaceHolder_EnumUserStrings(); - void PlaceHolder_GetParamForMethodIndex(); - void PlaceHolder_EnumCustomAttributes(); - void PlaceHolder_GetCustomAttributeProps(); - void PlaceHolder_FindTypeRef(); - void PlaceHolder_GetMemberProps(); - void PlaceHolder_GetFieldProps(); - void PlaceHolder_GetPropertyProps(); - void PlaceHolder_GetParamProps(); - void PlaceHolder_GetCustomAttributeByName(); - void PlaceHolder_IsValidToken(); - - void GetNestedClassProps( - int tdNestedClass, // [IN] NestedClass token. - IntPtr ptdEnclosingClass); // [OUT] EnclosingClass token. - - void PlaceHolder_GetNativeCallConvFromSig(); - void PlaceHolder_IsGlobal(); - } - - [Guid("ba3fee4c-ecb9-4e41-83b7-183fa41cd859")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - interface IMetaDataEmit - { - void PlaceHolder_SetModuleProps(); - void PlaceHolder_Save(); - void PlaceHolder_SaveToStream(); - void PlaceHolder_GetSaveSize(); - void PlaceHolder_DefineTypeDef(); - void PlaceHolder_DefineNestedType(); - void PlaceHolder_SetHandler(); - void PlaceHolder_DefineMethod(); - void PlaceHolder_DefineMethodImpl(); - void PlaceHolder_DefineTypeRefByName(); - void PlaceHolder_DefineImportType(); - void PlaceHolder_DefineMemberRef(); - void PlaceHolder_DefineImportMember(); - void PlaceHolder_DefineEvent(); - void PlaceHolder_SetClassLayout(); - void PlaceHolder_DeleteClassLayout(); - void PlaceHolder_SetFieldMarshal(); - void PlaceHolder_DeleteFieldMarshal(); - void PlaceHolder_DefinePermissionSet(); - void PlaceHolder_SetRVA(); - void PlaceHolder_GetTokenFromSig(); - void PlaceHolder_DefineModuleRef(); - void PlaceHolder_SetParent(); - void PlaceHolder_GetTokenFromTypeSpec(); - void PlaceHolder_SaveToMemory(); - void PlaceHolder_DefineUserString(); - void PlaceHolder_DeleteToken(); - void PlaceHolder_SetMethodProps(); - void PlaceHolder_SetTypeDefProps(); - void PlaceHolder_SetEventProps(); - void PlaceHolder_SetPermissionSetProps(); - void PlaceHolder_DefinePinvokeMap(); - void PlaceHolder_SetPinvokeMap(); - void PlaceHolder_DeletePinvokeMap(); - void PlaceHolder_DefineCustomAttribute(); - void PlaceHolder_SetCustomAttributeValue(); - void PlaceHolder_DefineField(); - void PlaceHolder_DefineProperty(); - void PlaceHolder_DefineParam(); - void PlaceHolder_SetFieldProps(); - void PlaceHolder_SetPropertyProps(); - void PlaceHolder_SetParamProps(); - void PlaceHolder_DefineSecurityAttributeSet(); - void PlaceHolder_ApplyEditAndContinue(); - void PlaceHolder_TranslateSigWithScope(); - void PlaceHolder_SetMethodImplFlags(); - void PlaceHolder_SetFieldRVA(); - void PlaceHolder_Merge(); - void PlaceHolder_MergeEnd(); - } - - [Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - internal interface ISymUnmanagedDocumentWriter { } - - [Guid("0b97726e-9e6d-4f05-9a26-424022093caa")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - [CoClass(typeof(CorSymWriterClass))] - interface ISymUnmanagedWriter2 - { - ISymUnmanagedDocumentWriter DefineDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType); - void PlaceHolder_SetUserEntryPoint(); - void OpenMethod(int method); - void CloseMethod(); - int OpenScope(int startOffset); - void CloseScope(int endOffset); - void PlaceHolder_SetScopeRange(); - void DefineLocalVariable(string name, int attributes, int cSig, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature, int addrKind, int addr1, int addr2, int startOffset, int endOffset); - void PlaceHolder_DefineParameter(); - void PlaceHolder_DefineField(); - void PlaceHolder_DefineGlobalVariable(); - void Close(); - void PlaceHolder_SetSymAttribute(); - void PlaceHolder_OpenNamespace(); - void PlaceHolder_CloseNamespace(); - void PlaceHolder_UsingNamespace(); - void PlaceHolder_SetMethodSourceRange(); - void Initialize([MarshalAs(UnmanagedType.IUnknown)] object emitter, string filename, [MarshalAs(UnmanagedType.IUnknown)] object pIStream, bool fFullBuild); - - void GetDebugInfo( - [In, Out] ref IMAGE_DEBUG_DIRECTORY pIDD, - [In] uint cData, - [Out] out uint pcData, - [Out, MarshalAs(UnmanagedType.LPArray)] byte[] data); - - void DefineSequencePoints(ISymUnmanagedDocumentWriter document, int spCount, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] offsets, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] lines, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] columns, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endLines, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endColumns); - - void RemapToken( - [In] int oldToken, - [In] int newToken); - - void PlaceHolder_Initialize2(); - void PlaceHolder_DefineConstant(); - void PlaceHolder_Abort(); - - void DefineLocalVariable2(string name, int attributes, int token, int addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset); - - void PlaceHolder_DefineGlobalVariable2(); - void PlaceHolder_DefineConstant2(); - } - - [Guid("108296c1-281e-11d3-bd22-0000f80849bd")] - [ComImport] - class CorSymWriterClass { } - - sealed class PdbWriter : ISymbolWriterImpl, IMetaDataEmit, IMetaDataImport - { - private readonly ModuleBuilder moduleBuilder; - private ISymUnmanagedWriter2 symUnmanagedWriter; - private readonly Dictionary documents = new Dictionary(); - private readonly List methods = new List(); - private readonly Dictionary remap = new Dictionary(); - private readonly Dictionary reversemap = new Dictionary(); - private readonly Dictionary methodMap = new Dictionary(); - private Method currentMethod; - - internal PdbWriter(ModuleBuilder moduleBuilder) - { - this.moduleBuilder = moduleBuilder; - } - - private sealed class Document : ISymbolDocumentWriter - { - internal readonly string url; - private Guid language; - private Guid languageVendor; - private Guid documentType; - private ISymUnmanagedDocumentWriter unmanagedDocument; - - internal Document(string url, Guid language, Guid languageVendor, Guid documentType) - { - this.url = url; - this.language = language; - this.languageVendor = languageVendor; - this.documentType = documentType; - } - - public void SetCheckSum(Guid algorithmId, byte[] checkSum) - { - throw new NotImplementedException(); - } - - public void SetSource(byte[] source) - { - throw new NotImplementedException(); - } - - internal ISymUnmanagedDocumentWriter GetUnmanagedDocument(ISymUnmanagedWriter2 symUnmanagedWriter) - { - if (unmanagedDocument == null) - { - unmanagedDocument = symUnmanagedWriter.DefineDocument(url, ref language, ref languageVendor, ref documentType); - } - return unmanagedDocument; - } - - internal void Release() - { - if (unmanagedDocument != null) - { - Marshal.ReleaseComObject(unmanagedDocument); - unmanagedDocument = null; - } - } - } - - private sealed class LocalVar - { - internal readonly FieldAttributes attributes; - internal readonly int signature; - internal readonly SymAddressKind addrKind; - internal readonly int addr1; - internal readonly int addr2; - internal readonly int addr3; - internal readonly int startOffset; - internal readonly int endOffset; - - internal LocalVar(FieldAttributes attributes, int signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) - { - this.attributes = attributes; - this.signature = signature; - this.addrKind = addrKind; - this.addr1 = addr1; - this.addr2 = addr2; - this.addr3 = addr3; - this.startOffset = startOffset; - this.endOffset = endOffset; - } - } - - private sealed class Scope - { - internal readonly int startOffset; - internal int endOffset; - internal readonly List scopes = new List(); - internal readonly Dictionary locals = new Dictionary(); - - internal Scope(int startOffset) - { - this.startOffset = startOffset; - } - - internal void Do(ISymUnmanagedWriter2 symUnmanagedWriter) - { - symUnmanagedWriter.OpenScope(startOffset); - foreach (KeyValuePair kv in locals) - { - symUnmanagedWriter.DefineLocalVariable2(kv.Key, (int)kv.Value.attributes, kv.Value.signature, (int)kv.Value.addrKind, kv.Value.addr1, kv.Value.addr2, kv.Value.addr3, kv.Value.startOffset, kv.Value.endOffset); - } - foreach (Scope scope in scopes) - { - scope.Do(symUnmanagedWriter); - } - symUnmanagedWriter.CloseScope(endOffset); - } - } - - private sealed class Method - { - internal readonly int token; - internal Document document; - internal int[] offsets; - internal int[] lines; - internal int[] columns; - internal int[] endLines; - internal int[] endColumns; - internal readonly List scopes = new List(); - internal readonly Stack scopeStack = new Stack(); - - internal Method(int token) - { - this.token = token; - } - } - - public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) - { - Document doc; - if (!documents.TryGetValue(url, out doc)) - { - doc = new Document(url, language, languageVendor, documentType); - documents.Add(url, doc); - } - return doc; - } - - public void OpenMethod(SymbolToken method) - { - throw new NotImplementedException(); - } - - public void OpenMethod(SymbolToken method, MethodBase mb) - { - int token = method.GetToken(); - currentMethod = new Method(token); - methodMap.Add(token, mb); - } - - public void CloseMethod() - { - methods.Add(currentMethod); - currentMethod = null; - } - - public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) - { - currentMethod.document = (Document)document; - currentMethod.offsets = offsets; - currentMethod.lines = lines; - currentMethod.columns = columns; - currentMethod.endLines = endLines; - currentMethod.endColumns = endColumns; - } - - public int OpenScope(int startOffset) - { - Scope scope = new Scope(startOffset); - if (currentMethod.scopeStack.Count == 0) - { - currentMethod.scopes.Add(scope); - } - else - { - currentMethod.scopeStack.Peek().scopes.Add(scope); - } - currentMethod.scopeStack.Push(scope); - return 0; - } - - public void CloseScope(int endOffset) - { - currentMethod.scopeStack.Pop().endOffset = endOffset; - } - - public void DefineLocalVariable2(string name, FieldAttributes attributes, int signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) - { - currentMethod.scopeStack.Peek().locals[name] = new LocalVar(attributes, signature, addrKind, addr1, addr2, addr3, startOffset, endOffset); - } - - private void InitWriter() - { - if (symUnmanagedWriter == null) - { - string fileName = System.IO.Path.ChangeExtension(moduleBuilder.FullyQualifiedName, ".pdb"); - // pro-actively delete the .pdb to get a meaningful IOException, instead of COMInteropException if the file can't be overwritten (or is corrupt, or who knows what) - System.IO.File.Delete(fileName); - symUnmanagedWriter = new ISymUnmanagedWriter2(); - symUnmanagedWriter.Initialize(this, fileName, null, true); - } - } - - public byte[] GetDebugInfo(ref IMAGE_DEBUG_DIRECTORY idd) - { - InitWriter(); - uint cData; - symUnmanagedWriter.GetDebugInfo(ref idd, 0, out cData, null); - byte[] buf = new byte[cData]; - symUnmanagedWriter.GetDebugInfo(ref idd, (uint)buf.Length, out cData, buf); - return buf; - } - - public void RemapToken(int oldToken, int newToken) - { - remap.Add(oldToken, newToken); - reversemap.Add(newToken, oldToken); - } - - public void Close() - { - InitWriter(); - - foreach (Method method in methods) - { - int remappedToken = method.token; - remap.TryGetValue(remappedToken, out remappedToken); - symUnmanagedWriter.OpenMethod(remappedToken); - if (method.document != null) - { - ISymUnmanagedDocumentWriter doc = method.document.GetUnmanagedDocument(symUnmanagedWriter); - symUnmanagedWriter.DefineSequencePoints(doc, method.offsets.Length, method.offsets, method.lines, method.columns, method.endLines, method.endColumns); - } - foreach (Scope scope in method.scopes) - { - scope.Do(symUnmanagedWriter); - } - symUnmanagedWriter.CloseMethod(); - } - - foreach (Document doc in documents.Values) - { - doc.Release(); - } - - symUnmanagedWriter.Close(); - Marshal.ReleaseComObject(symUnmanagedWriter); - symUnmanagedWriter = null; - documents.Clear(); - methods.Clear(); - remap.Clear(); - reversemap.Clear(); - } - - public void DefineLocalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) - { - throw new NotImplementedException(); - } - - public void CloseNamespace() - { - throw new NotImplementedException(); - } - - public void DefineField(SymbolToken parent, string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - throw new NotImplementedException(); - } - - public void DefineGlobalVariable(string name, System.Reflection.FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - throw new NotImplementedException(); - } - - public void DefineParameter(string name, System.Reflection.ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) - { - throw new NotImplementedException(); - } - - public void Initialize(IntPtr emitter, string filename, bool fFullBuild) - { - throw new NotImplementedException(); - } - - public void OpenNamespace(string name) - { - throw new NotImplementedException(); - } - - public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) - { - throw new NotImplementedException(); - } - - public void SetScopeRange(int scopeID, int startOffset, int endOffset) - { - throw new NotImplementedException(); - } - - public void SetSymAttribute(SymbolToken parent, string name, byte[] data) - { - throw new NotImplementedException(); - } - - public void SetUnderlyingWriter(IntPtr underlyingWriter) - { - throw new NotImplementedException(); - } - - public void SetUserEntryPoint(SymbolToken entryMethod) - { - throw new NotImplementedException(); - } - - public void UsingNamespace(string fullName) - { - throw new NotImplementedException(); - } - - public void PlaceHolder_CloseEnum() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_CountEnum() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_ResetEnum() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumTypeDefs() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumInterfaceImpls() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumTypeRefs() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindTypeDefByName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetScopeProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetModuleFromScope() - { - throw new NotImplementedException(); - } - - private static void WriteString(IntPtr ptrString, IntPtr ptrLength, string str, int length) - { - if (ptrString != IntPtr.Zero) - { - for (int i = 0; i < Math.Min(length, str.Length); i++) - { - Marshal.WriteInt16(ptrString, i, str[i]); - } - } - if (ptrLength != IntPtr.Zero) - { - Marshal.WriteInt32(ptrLength, str.Length); - } - } - - private static void WriteToken(IntPtr ptr, MemberInfo member) - { - if (ptr != IntPtr.Zero) - { - Marshal.WriteInt32(ptr, member == null ? 0 : member.MetadataToken); - } - } - - private static void WriteInt32(IntPtr ptr, int value) - { - if (ptr != IntPtr.Zero) - { - Marshal.WriteInt32(ptr, value); - } - } - - public void GetTypeDefProps( - int td, // [IN] TypeDef token for inquiry. - IntPtr szTypeDef, // [OUT] Put name here. - int cchTypeDef, // [IN] size of name buffer in wide chars. - IntPtr pchTypeDef, // [OUT] put size of name (wide chars) here. - IntPtr pdwTypeDefFlags, // [OUT] Put flags here. - IntPtr ptkExtends) // [OUT] Put base class TypeDef/TypeRef here. - { - if (td == 0) - { - // why are we being called with an invalid token? - WriteString(szTypeDef, pchTypeDef, "", cchTypeDef); - WriteInt32(pdwTypeDefFlags, 0); - WriteToken(ptkExtends, null); - } - else - { - Type type = moduleBuilder.ResolveType(td); - WriteString(szTypeDef, pchTypeDef, type.FullName, cchTypeDef); - WriteInt32(pdwTypeDefFlags, (int)type.Attributes); - WriteToken(ptkExtends, type.BaseType); - } - } - - public void PlaceHolder_GetInterfaceImplProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetTypeRefProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_ResolveTypeRef() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMembers() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMembersWithName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMethods() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMethodsWithName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumFields() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumFieldsWithName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumParams() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMemberRefs() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMethodImpls() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumPermissionSets() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindMember() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindMethod() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindField() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindMemberRef() - { - throw new NotImplementedException(); - } - - public void GetMethodProps( - int mb, // The method for which to get props. - IntPtr pClass, // [OUT] Put method's class here. - IntPtr szMethod, // [OUT] Put method's name here. - int cchMethod, // Size of szMethod buffer in wide chars. - IntPtr pchMethod, // [OUT] Put actual size here - IntPtr pdwAttr, // [OUT] Put flags here. - IntPtr ppvSigBlob, // [OUT] point to the blob value of meta data - IntPtr pcbSigBlob, // [OUT] actual size of signature blob - IntPtr pulCodeRVA, // [OUT] codeRVA - IntPtr pdwImplFlags) // [OUT] Impl. Flags - { - if (pdwAttr != IntPtr.Zero || ppvSigBlob != IntPtr.Zero || pcbSigBlob != IntPtr.Zero || pulCodeRVA != IntPtr.Zero || pdwImplFlags != IntPtr.Zero) - { - throw new NotImplementedException(); - } - MethodBase method = methodMap[reversemap[mb]]; - WriteToken(pClass, method.DeclaringType); - WriteString(szMethod, pchMethod, method.Name, cchMethod); - } - - public void PlaceHolder_GetMemberRefProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumProperties() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumEvents() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetEventProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumMethodSemantics() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetMethodSemantics() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetClassLayout() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetFieldMarshal() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetRVA() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetPermissionSetProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetSigFromToken() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetModuleRefProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumModuleRefs() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetTypeSpecFromToken() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetNameFromToken() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumUnresolvedMethods() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetUserString() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetPinvokeMap() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumSignatures() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumTypeSpecs() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumUserStrings() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetParamForMethodIndex() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_EnumCustomAttributes() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetCustomAttributeProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_FindTypeRef() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetMemberProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetFieldProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetPropertyProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetParamProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetCustomAttributeByName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_IsValidToken() - { - throw new NotImplementedException(); - } - - public void GetNestedClassProps( - int tdNestedClass, // [IN] NestedClass token. - IntPtr ptdEnclosingClass) // [OUT] EnclosingClass token. - { - Type type = moduleBuilder.ResolveType(tdNestedClass); - WriteToken(ptdEnclosingClass, type.DeclaringType); - } - - public void PlaceHolder_GetNativeCallConvFromSig() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_IsGlobal() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetModuleProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_Save() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SaveToStream() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetSaveSize() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineTypeDef() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineNestedType() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetHandler() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineMethod() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineMethodImpl() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineTypeRefByName() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineImportType() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineMemberRef() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineImportMember() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineEvent() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetClassLayout() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DeleteClassLayout() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetFieldMarshal() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DeleteFieldMarshal() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefinePermissionSet() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetRVA() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetTokenFromSig() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineModuleRef() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetParent() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_GetTokenFromTypeSpec() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SaveToMemory() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineUserString() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DeleteToken() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetMethodProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetTypeDefProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetEventProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetPermissionSetProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefinePinvokeMap() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetPinvokeMap() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DeletePinvokeMap() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineCustomAttribute() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetCustomAttributeValue() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineField() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineProperty() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineParam() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetFieldProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetPropertyProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetParamProps() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_DefineSecurityAttributeSet() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_ApplyEditAndContinue() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_TranslateSigWithScope() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetMethodImplFlags() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_SetFieldRVA() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_Merge() - { - throw new NotImplementedException(); - } - - public void PlaceHolder_MergeEnd() - { - throw new NotImplementedException(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Impl/SymbolSupport.cs b/mcs/class/IKVM.Reflection/Impl/SymbolSupport.cs deleted file mode 100644 index 64547ebe8ed..00000000000 --- a/mcs/class/IKVM.Reflection/Impl/SymbolSupport.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2008, 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.InteropServices; -using System.Diagnostics.SymbolStore; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection.Impl -{ - [StructLayout(LayoutKind.Sequential)] - struct IMAGE_DEBUG_DIRECTORY - { - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public uint Type; - public uint SizeOfData; - public uint AddressOfRawData; - public uint PointerToRawData; - } - - interface ISymbolWriterImpl : ISymbolWriter - { - byte[] GetDebugInfo(ref IMAGE_DEBUG_DIRECTORY idd); - void RemapToken(int oldToken, int newToken); - void DefineLocalVariable2(string name, FieldAttributes attributes, int signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset); - void OpenMethod(SymbolToken symbolToken, MethodBase mb); - } - - static class SymbolSupport - { - internal static ISymbolWriterImpl CreateSymbolWriterFor(ModuleBuilder moduleBuilder) - { -#if NO_SYMBOL_WRITER - throw new NotSupportedException("IKVM.Reflection compiled with NO_SYMBOL_WRITER does not support writing debugging symbols."); -#else - if (Universe.MonoRuntime) - { -#if MONO - return new MdbWriter(moduleBuilder); -#else - throw new NotSupportedException("IKVM.Reflection must be compiled with MONO defined to support writing Mono debugging symbols."); -#endif - } - else - { - return new PdbWriter(moduleBuilder); - } -#endif - } - - internal static byte[] GetDebugInfo(ISymbolWriterImpl writer, ref IMAGE_DEBUG_DIRECTORY idd) - { - return writer.GetDebugInfo(ref idd); - } - - internal static void RemapToken(ISymbolWriterImpl writer, int oldToken, int newToken) - { - writer.RemapToken(oldToken, newToken); - } - } -} diff --git a/mcs/class/IKVM.Reflection/InterfaceMapping.cs b/mcs/class/IKVM.Reflection/InterfaceMapping.cs deleted file mode 100644 index f589cfe951d..00000000000 --- a/mcs/class/IKVM.Reflection/InterfaceMapping.cs +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection -{ - public struct InterfaceMapping - { - public MethodInfo[] InterfaceMethods; - public Type InterfaceType; - public MethodInfo[] TargetMethods; - public Type TargetType; - } -} diff --git a/mcs/class/IKVM.Reflection/LocalVariableInfo.cs b/mcs/class/IKVM.Reflection/LocalVariableInfo.cs deleted file mode 100644 index e7f056781c2..00000000000 --- a/mcs/class/IKVM.Reflection/LocalVariableInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection -{ - public sealed class LocalVariableInfo - { - private readonly int index; - private readonly Type type; - private readonly bool pinned; - private readonly CustomModifiers customModifiers; - - internal LocalVariableInfo(int index, Type type, bool pinned, CustomModifiers customModifiers) - { - this.index = index; - this.type = type; - this.pinned = pinned; - this.customModifiers = customModifiers; - } - - public bool IsPinned - { - get { return pinned; } - } - - public int LocalIndex - { - get { return index; } - } - - public Type LocalType - { - get { return type; } - } - - public CustomModifiers __GetCustomModifiers() - { - return customModifiers; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Makefile b/mcs/class/IKVM.Reflection/Makefile deleted file mode 100644 index 069df18f31e..00000000000 --- a/mcs/class/IKVM.Reflection/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -thisdir = class/IKVM.Reflection -SUBDIRS = - -include ../../build/rules.make - -DISTFILES = \ - Emit/*.cs \ - Impl/*.cs \ - Metadata/*.cs \ - Properties/*.cs \ - Reader/*.cs \ - Writer/*.cs \ - *.cs *.csproj \ - Makefile - -all-local install-local clean-local test-local run-test-local run-test-ondotnet-local uninstall-local doc-update-local csproj-local: - -dist-local: dist-default diff --git a/mcs/class/IKVM.Reflection/ManifestResourceInfo.cs b/mcs/class/IKVM.Reflection/ManifestResourceInfo.cs deleted file mode 100644 index 04a2a306ed4..00000000000 --- a/mcs/class/IKVM.Reflection/ManifestResourceInfo.cs +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection -{ - public sealed class ManifestResourceInfo - { - private readonly ModuleReader module; - private readonly int index; - - internal ManifestResourceInfo(ModuleReader module, int index) - { - this.module = module; - this.index = index; - } - - public ResourceAttributes __ResourceAttributes - { - get { return (ResourceAttributes)module.ManifestResource.records[index].Flags; } - } - - public int __Offset - { - get { return module.ManifestResource.records[index].Offset; } - } - - public ResourceLocation ResourceLocation - { - get - { - int implementation = module.ManifestResource.records[index].Implementation; - if ((implementation >> 24) == AssemblyRefTable.Index) - { - Assembly asm = ReferencedAssembly; - if (asm == null || asm.__IsMissing) - { - return ResourceLocation.ContainedInAnotherAssembly; - } - return asm.GetManifestResourceInfo(module.GetString(module.ManifestResource.records[index].Name)).ResourceLocation | ResourceLocation.ContainedInAnotherAssembly; - } - else if ((implementation >> 24) == FileTable.Index) - { - if ((implementation & 0xFFFFFF) == 0) - { - return ResourceLocation.ContainedInManifestFile | ResourceLocation.Embedded; - } - return 0; - } - else - { - throw new BadImageFormatException(); - } - } - } - - public Assembly ReferencedAssembly - { - get - { - int implementation = module.ManifestResource.records[index].Implementation; - if ((implementation >> 24) == AssemblyRefTable.Index) - { - return module.ResolveAssemblyRef((implementation & 0xFFFFFF) - 1); - } - return null; - } - } - - public string FileName - { - get - { - int implementation = module.ManifestResource.records[index].Implementation; - if ((implementation >> 24) == FileTable.Index) - { - if ((implementation & 0xFFFFFF) == 0) - { - return null; - } - else - { - return module.GetString(module.File.records[(implementation & 0xFFFFFF) - 1].Name); - } - } - return null; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/MarshalSpec.cs b/mcs/class/IKVM.Reflection/MarshalSpec.cs deleted file mode 100644 index f568a68bb98..00000000000 --- a/mcs/class/IKVM.Reflection/MarshalSpec.cs +++ /dev/null @@ -1,259 +0,0 @@ -/* - Copyright (C) 2008-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection -{ - public struct FieldMarshal - { - private const UnmanagedType NATIVE_TYPE_MAX = (UnmanagedType)0x50; - public UnmanagedType UnmanagedType; - public UnmanagedType? ArraySubType; - public short? SizeParamIndex; - public int? SizeConst; - public VarEnum? SafeArraySubType; - public Type SafeArrayUserDefinedSubType; - public int? IidParameterIndex; - public string MarshalType; - public string MarshalCookie; - public Type MarshalTypeRef; - - internal static bool ReadFieldMarshal(Module module, int token, out FieldMarshal fm) - { - fm = new FieldMarshal(); - foreach (int i in module.FieldMarshal.Filter(token)) - { - ByteReader blob = module.GetBlob(module.FieldMarshal.records[i].NativeType); - fm.UnmanagedType = (UnmanagedType)blob.ReadCompressedInt(); - if (fm.UnmanagedType == UnmanagedType.LPArray) - { - fm.ArraySubType = (UnmanagedType)blob.ReadCompressedInt(); - if (fm.ArraySubType == NATIVE_TYPE_MAX) - { - fm.ArraySubType = null; - } - if (blob.Length != 0) - { - fm.SizeParamIndex = (short)blob.ReadCompressedInt(); - if (blob.Length != 0) - { - fm.SizeConst = blob.ReadCompressedInt(); - if (blob.Length != 0 && blob.ReadCompressedInt() == 0) - { - fm.SizeParamIndex = null; - } - } - } - } - else if (fm.UnmanagedType == UnmanagedType.SafeArray) - { - if (blob.Length != 0) - { - fm.SafeArraySubType = (VarEnum)blob.ReadCompressedInt(); - if (blob.Length != 0) - { - fm.SafeArrayUserDefinedSubType = ReadType(module, blob); - } - } - } - else if (fm.UnmanagedType == UnmanagedType.ByValArray) - { - fm.SizeConst = blob.ReadCompressedInt(); - if (blob.Length != 0) - { - fm.ArraySubType = (UnmanagedType)blob.ReadCompressedInt(); - } - } - else if (fm.UnmanagedType == UnmanagedType.ByValTStr) - { - fm.SizeConst = blob.ReadCompressedInt(); - } - else if (fm.UnmanagedType == UnmanagedType.Interface - || fm.UnmanagedType == UnmanagedType.IDispatch - || fm.UnmanagedType == UnmanagedType.IUnknown) - { - if (blob.Length != 0) - { - fm.IidParameterIndex = blob.ReadCompressedInt(); - } - } - else if (fm.UnmanagedType == UnmanagedType.CustomMarshaler) - { - blob.ReadCompressedInt(); - blob.ReadCompressedInt(); - fm.MarshalType = ReadString(blob); - fm.MarshalCookie = ReadString(blob); - - TypeNameParser parser = TypeNameParser.Parse(fm.MarshalType, false); - if (!parser.Error) - { - fm.MarshalTypeRef = parser.GetType(module.universe, module.Assembly, false, fm.MarshalType, false, false); - } - } - return true; - } - return false; - } - - internal static void SetMarshalAsAttribute(ModuleBuilder module, int token, CustomAttributeBuilder attribute) - { - attribute = attribute.DecodeBlob(module.Assembly); - FieldMarshalTable.Record rec = new FieldMarshalTable.Record(); - rec.Parent = token; - rec.NativeType = WriteMarshallingDescriptor(module, attribute); - module.FieldMarshal.AddRecord(rec); - } - - private static int WriteMarshallingDescriptor(ModuleBuilder module, CustomAttributeBuilder attribute) - { - UnmanagedType unmanagedType; - object val = attribute.GetConstructorArgument(0); - if (val is short) - { - unmanagedType = (UnmanagedType)(short)val; - } - else if (val is int) - { - unmanagedType = (UnmanagedType)(int)val; - } - else - { - unmanagedType = (UnmanagedType)val; - } - - ByteBuffer bb = new ByteBuffer(5); - bb.WriteCompressedInt((int)unmanagedType); - - if (unmanagedType == UnmanagedType.LPArray) - { - UnmanagedType arraySubType = attribute.GetFieldValue("ArraySubType") ?? NATIVE_TYPE_MAX; - bb.WriteCompressedInt((int)arraySubType); - int? sizeParamIndex = attribute.GetFieldValue("SizeParamIndex"); - int? sizeConst = attribute.GetFieldValue("SizeConst"); - if (sizeParamIndex != null) - { - bb.WriteCompressedInt(sizeParamIndex.Value); - if (sizeConst != null) - { - bb.WriteCompressedInt(sizeConst.Value); - bb.WriteCompressedInt(1); // flag that says that SizeParamIndex was specified - } - } - else if (sizeConst != null) - { - bb.WriteCompressedInt(0); // SizeParamIndex - bb.WriteCompressedInt(sizeConst.Value); - bb.WriteCompressedInt(0); // flag that says that SizeParamIndex was not specified - } - } - else if (unmanagedType == UnmanagedType.SafeArray) - { - VarEnum? safeArraySubType = attribute.GetFieldValue("SafeArraySubType"); - if (safeArraySubType != null) - { - bb.WriteCompressedInt((int)safeArraySubType); - Type safeArrayUserDefinedSubType = (Type)attribute.GetFieldValue("SafeArrayUserDefinedSubType"); - if (safeArrayUserDefinedSubType != null) - { - WriteType(module, bb, safeArrayUserDefinedSubType); - } - } - } - else if (unmanagedType == UnmanagedType.ByValArray) - { - bb.WriteCompressedInt(attribute.GetFieldValue("SizeConst") ?? 1); - UnmanagedType? arraySubType = attribute.GetFieldValue("ArraySubType"); - if (arraySubType != null) - { - bb.WriteCompressedInt((int)arraySubType); - } - } - else if (unmanagedType == UnmanagedType.ByValTStr) - { - bb.WriteCompressedInt(attribute.GetFieldValue("SizeConst").Value); - } - else if (unmanagedType == UnmanagedType.Interface - || unmanagedType == UnmanagedType.IDispatch - || unmanagedType == UnmanagedType.IUnknown) - { - int? iidParameterIndex = attribute.GetFieldValue("IidParameterIndex"); - if (iidParameterIndex != null) - { - bb.WriteCompressedInt(iidParameterIndex.Value); - } - } - else if (unmanagedType == UnmanagedType.CustomMarshaler) - { - bb.WriteCompressedInt(0); - bb.WriteCompressedInt(0); - string marshalType = (string)attribute.GetFieldValue("MarshalType"); - if (marshalType != null) - { - WriteString(bb, marshalType); - } - else - { - WriteType(module, bb, (Type)attribute.GetFieldValue("MarshalTypeRef")); - } - WriteString(bb, (string)attribute.GetFieldValue("MarshalCookie") ?? ""); - } - - return module.Blobs.Add(bb); - } - - private static Type ReadType(Module module, ByteReader br) - { - string str = ReadString(br); - if (str == "") - { - return null; - } - return module.Assembly.GetType(str) ?? module.universe.GetType(str, true); - } - - private static void WriteType(Module module, ByteBuffer bb, Type type) - { - WriteString(bb, type.Assembly == module.Assembly ? type.FullName : type.AssemblyQualifiedName); - } - - private static string ReadString(ByteReader br) - { - return Encoding.UTF8.GetString(br.ReadBytes(br.ReadCompressedInt())); - } - - private static void WriteString(ByteBuffer bb, string str) - { - byte[] buf = Encoding.UTF8.GetBytes(str); - bb.WriteCompressedInt(buf.Length); - bb.Write(buf); - } - } -} diff --git a/mcs/class/IKVM.Reflection/MemberInfo.cs b/mcs/class/IKVM.Reflection/MemberInfo.cs deleted file mode 100644 index 0f9438c8ca0..00000000000 --- a/mcs/class/IKVM.Reflection/MemberInfo.cs +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ -// disable warnings that complain about us having == and != operators without also overriding Equals/GetHashCode, -// this is intentional because most subtypes use reference equality -#pragma warning disable 660, 661 - public abstract class MemberInfo : ICustomAttributeProvider - { - // prevent external subclasses - internal MemberInfo() - { - } - - public abstract string Name { get; } - public abstract Type DeclaringType { get; } - public abstract MemberTypes MemberType { get; } - - public virtual Type ReflectedType - { - get { return DeclaringType; } - } - - internal abstract MemberInfo SetReflectedType(Type type); - - public virtual int MetadataToken - { - get { throw new NotSupportedException(); } - } - - public abstract Module Module - { - get; - } - - public virtual bool __IsMissing - { - get { return false; } - } - - public bool IsDefined(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0; - } - - public IList __GetCustomAttributes(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit); - } - - public static bool operator ==(MemberInfo m1, MemberInfo m2) - { - return ReferenceEquals(m1, m2) || (!ReferenceEquals(m1, null) && m1.Equals(m2)); - } - - public static bool operator !=(MemberInfo m1, MemberInfo m2) - { - return !(m1 == m2); - } - - internal abstract int GetCurrentToken(); - - internal abstract List GetPseudoCustomAttributes(Type attributeType); - - internal abstract bool IsBaked { get; } - - internal virtual bool BindingFlagsMatch(BindingFlags flags) - { - throw new InvalidOperationException(); - } - - internal virtual bool BindingFlagsMatchInherited(BindingFlags flags) - { - throw new InvalidOperationException(); - } - - protected static bool BindingFlagsMatch(bool state, BindingFlags flags, BindingFlags trueFlag, BindingFlags falseFlag) - { - return (state && (flags & trueFlag) == trueFlag) - || (!state && (flags & falseFlag) == falseFlag); - } - - protected static T SetReflectedType(T member, Type type) - where T : MemberInfo - { - return member == null ? null : (T)member.SetReflectedType(type); - } - - protected static T[] SetReflectedType(T[] members, Type type) - where T : MemberInfo - { - for (int i = 0; i < members.Length; i++) - { - members[i] = SetReflectedType(members[i], type); - } - return members; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Metadata/CliHeader.cs b/mcs/class/IKVM.Reflection/Metadata/CliHeader.cs deleted file mode 100644 index 32812290f7e..00000000000 --- a/mcs/class/IKVM.Reflection/Metadata/CliHeader.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System.IO; -using IMAGE_DATA_DIRECTORY = IKVM.Reflection.Reader.IMAGE_DATA_DIRECTORY; - -namespace IKVM.Reflection.Metadata -{ - sealed class CliHeader - { - internal const uint COMIMAGE_FLAGS_ILONLY = 0x00000001; - internal const uint COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002; - internal const uint COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x00000008; - internal const uint COMIMAGE_FLAGS_NATIVE_ENTRYPOINT = 0x00000010; - internal const uint COMIMAGE_FLAGS_32BITPREFERRED = 0x00020000; - - internal uint Cb = 0x48; - internal ushort MajorRuntimeVersion; - internal ushort MinorRuntimeVersion; - internal IMAGE_DATA_DIRECTORY MetaData; - internal uint Flags; - internal uint EntryPointToken; - internal IMAGE_DATA_DIRECTORY Resources; - internal IMAGE_DATA_DIRECTORY StrongNameSignature; - internal IMAGE_DATA_DIRECTORY CodeManagerTable; - internal IMAGE_DATA_DIRECTORY VTableFixups; - internal IMAGE_DATA_DIRECTORY ExportAddressTableJumps; - internal IMAGE_DATA_DIRECTORY ManagedNativeHeader; - - internal void Read(BinaryReader br) - { - Cb = br.ReadUInt32(); - MajorRuntimeVersion = br.ReadUInt16(); - MinorRuntimeVersion = br.ReadUInt16(); - MetaData.Read(br); - Flags = br.ReadUInt32(); - EntryPointToken = br.ReadUInt32(); - Resources.Read(br); - StrongNameSignature.Read(br); - CodeManagerTable.Read(br); - VTableFixups.Read(br); - ExportAddressTableJumps.Read(br); - ManagedNativeHeader.Read(br); - } - - internal void Write(IKVM.Reflection.Writer.MetadataWriter mw) - { - mw.Write(Cb); - mw.Write(MajorRuntimeVersion); - mw.Write(MinorRuntimeVersion); - MetaData.Write(mw); - mw.Write(Flags); - mw.Write(EntryPointToken); - Resources.Write(mw); - StrongNameSignature.Write(mw); - CodeManagerTable.Write(mw); - VTableFixups.Write(mw); - ExportAddressTableJumps.Write(mw); - ManagedNativeHeader.Write(mw); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Metadata/MetadataRW.cs b/mcs/class/IKVM.Reflection/Metadata/MetadataRW.cs deleted file mode 100644 index d03c8d62897..00000000000 --- a/mcs/class/IKVM.Reflection/Metadata/MetadataRW.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection.Metadata -{ - // base class for MetadataReader and MetadataWriter - abstract class MetadataRW - { - internal readonly bool bigStrings; - internal readonly bool bigGuids; - internal readonly bool bigBlobs; - internal readonly bool bigResolutionScope; - internal readonly bool bigTypeDefOrRef; - internal readonly bool bigMemberRefParent; - internal readonly bool bigHasCustomAttribute; - internal readonly bool bigCustomAttributeType; - internal readonly bool bigMethodDefOrRef; - internal readonly bool bigHasConstant; - internal readonly bool bigHasSemantics; - internal readonly bool bigHasFieldMarshal; - internal readonly bool bigHasDeclSecurity; - internal readonly bool bigTypeOrMethodDef; - internal readonly bool bigMemberForwarded; - internal readonly bool bigImplementation; - internal readonly bool bigField; - internal readonly bool bigMethodDef; - internal readonly bool bigParam; - internal readonly bool bigTypeDef; - internal readonly bool bigProperty; - internal readonly bool bigEvent; - internal readonly bool bigGenericParam; - internal readonly bool bigModuleRef; - - protected MetadataRW(Module module, bool bigStrings, bool bigGuids, bool bigBlobs) - { - this.bigStrings = bigStrings; - this.bigGuids = bigGuids; - this.bigBlobs = bigBlobs; - this.bigField = module.Field.IsBig; - this.bigMethodDef = module.MethodDef.IsBig; - this.bigParam = module.Param.IsBig; - this.bigTypeDef = module.TypeDef.IsBig; - this.bigProperty = module.Property.IsBig; - this.bigEvent = module.Event.IsBig; - this.bigGenericParam = module.GenericParam.IsBig; - this.bigModuleRef = module.ModuleRef.IsBig; - this.bigResolutionScope = IsBig(2, module.ModuleTable, module.ModuleRef, module.AssemblyRef, module.TypeRef); - this.bigTypeDefOrRef = IsBig(2, module.TypeDef, module.TypeRef, module.TypeSpec); - this.bigMemberRefParent = IsBig(3, module.TypeDef, module.TypeRef, module.ModuleRef, module.MethodDef, module.TypeSpec); - this.bigMethodDefOrRef = IsBig(1, module.MethodDef, module.MemberRef); - this.bigHasCustomAttribute = IsBig(5, module.MethodDef, module.Field, module.TypeRef, module.TypeDef, module.Param, module.InterfaceImpl, module.MemberRef, - module.ModuleTable, /*module.Permission,*/ module.Property, module.Event, module.StandAloneSig, module.ModuleRef, module.TypeSpec, module.AssemblyTable, - module.AssemblyRef, module.File, module.ExportedType, module.ManifestResource); - this.bigCustomAttributeType = IsBig(3, module.MethodDef, module.MemberRef); - this.bigHasConstant = IsBig(2, module.Field, module.Param, module.Property); - this.bigHasSemantics = IsBig(1, module.Event, module.Property); - this.bigHasFieldMarshal = IsBig(1, module.Field, module.Param); - this.bigHasDeclSecurity = IsBig(2, module.TypeDef, module.MethodDef, module.AssemblyTable); - this.bigTypeOrMethodDef = IsBig(1, module.TypeDef, module.MethodDef); - this.bigMemberForwarded = IsBig(1, module.Field, module.MethodDef); - this.bigImplementation = IsBig(2, module.File, module.AssemblyRef, module.ExportedType); - } - - private static bool IsBig(int bitsUsed, params Table[] tables) - { - int limit = 1 << (16 - bitsUsed); - foreach (Table table in tables) - { - if (table.RowCount >= limit) - { - return true; - } - } - return false; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Metadata/Tables.cs b/mcs/class/IKVM.Reflection/Metadata/Tables.cs deleted file mode 100644 index ad61cb04e77..00000000000 --- a/mcs/class/IKVM.Reflection/Metadata/Tables.cs +++ /dev/null @@ -1,2724 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection.Metadata -{ - internal abstract class Table - { - internal bool Sorted; - - internal bool IsBig - { - get { return RowCount > 65535; } - } - - internal abstract int RowCount { get; set; } - - internal abstract void Write(MetadataWriter mw); - internal abstract void Read(MetadataReader mr); - - internal int GetLength(MetadataWriter md) - { - return RowCount * GetRowSize(new RowSizeCalc(md)); - } - - protected abstract int GetRowSize(RowSizeCalc rsc); - - protected sealed class RowSizeCalc - { - private readonly MetadataWriter mw; - private int size; - - internal RowSizeCalc(MetadataWriter mw) - { - this.mw = mw; - } - - internal RowSizeCalc AddFixed(int size) - { - this.size += size; - return this; - } - - internal RowSizeCalc WriteStringIndex() - { - if (mw.bigStrings) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteGuidIndex() - { - if (mw.bigGuids) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteBlobIndex() - { - if (mw.bigBlobs) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteTypeDefOrRef() - { - if (mw.bigTypeDefOrRef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteField() - { - if (mw.bigField) - { - size += 4; - } - else - { - size += 2; - } - return this; - } - - internal RowSizeCalc WriteMethodDef() - { - if (mw.bigMethodDef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteParam() - { - if (mw.bigParam) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteResolutionScope() - { - if (mw.bigResolutionScope) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteMemberRefParent() - { - if (mw.bigMemberRefParent) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteHasCustomAttribute() - { - if (mw.bigHasCustomAttribute) - { - size += 4; - } - else - { - size += 2; - } - return this; - } - - internal RowSizeCalc WriteCustomAttributeType() - { - if (mw.bigCustomAttributeType) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteHasConstant() - { - if (mw.bigHasConstant) - { - size += 4; - } - else - { - size += 2; - } - return this; - } - - internal RowSizeCalc WriteTypeDef() - { - if (mw.bigTypeDef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteMethodDefOrRef() - { - if (mw.bigMethodDefOrRef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteEvent() - { - if (mw.bigEvent) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteProperty() - { - if (mw.bigProperty) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteHasSemantics() - { - if (mw.bigHasSemantics) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteImplementation() - { - if (mw.bigImplementation) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteTypeOrMethodDef() - { - if (mw.bigTypeOrMethodDef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteGenericParam() - { - if (mw.bigGenericParam) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteHasDeclSecurity() - { - if (mw.bigHasDeclSecurity) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteMemberForwarded() - { - if (mw.bigMemberForwarded) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteModuleRef() - { - if (mw.bigModuleRef) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal RowSizeCalc WriteHasFieldMarshal() - { - if (mw.bigHasFieldMarshal) - { - this.size += 4; - } - else - { - this.size += 2; - } - return this; - } - - internal int Value - { - get { return size; } - } - } - } - - abstract class Table : Table - { - internal T[] records = new T[1]; - protected int rowCount; - - internal sealed override int RowCount - { - get { return rowCount; } - set { rowCount = value; records = new T[value]; } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - throw new InvalidOperationException(); - } - - internal int AddRecord(T newRecord) - { - if (rowCount == records.Length) - { - T[] newarr = new T[records.Length * 2]; - Array.Copy(records, newarr, records.Length); - records = newarr; - } - records[rowCount++] = newRecord; - return rowCount; - } - - internal int AddVirtualRecord() - { - return ++rowCount; - } - - internal override void Write(MetadataWriter mw) - { - throw new InvalidOperationException(); - } - } - - abstract class SortedTable : Table - where T : SortedTable.IRecord - { - internal interface IRecord - { - int SortKey { get; } - int FilterKey { get; } - } - - internal struct Enumerable - { - private readonly SortedTable table; - private readonly int token; - - internal Enumerable(SortedTable table, int token) - { - this.table = table; - this.token = token; - } - - public Enumerator GetEnumerator() - { - T[] records = table.records; - if (!table.Sorted) - { - return new Enumerator(records, table.RowCount - 1, -1, token); - } - int index = BinarySearch(records, table.RowCount, token & 0xFFFFFF); - if (index < 0) - { - return new Enumerator(null, 0, 1, -1); - } - int start = index; - while (start > 0 && (records[start - 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF)) - { - start--; - } - int end = index; - int max = table.RowCount - 1; - while (end < max && (records[end + 1].FilterKey & 0xFFFFFF) == (token & 0xFFFFFF)) - { - end++; - } - return new Enumerator(records, end, start - 1, token); - } - - private static int BinarySearch(T[] records, int length, int maskedToken) - { - int min = 0; - int max = length - 1; - while (min <= max) - { - int mid = min + ((max - min) / 2); - int maskedValue = records[mid].FilterKey & 0xFFFFFF; - if (maskedToken == maskedValue) - { - return mid; - } - else if (maskedToken < maskedValue) - { - max = mid - 1; - } - else - { - min = mid + 1; - } - } - return -1; - } - } - - internal struct Enumerator - { - private readonly T[] records; - private readonly int token; - private readonly int max; - private int index; - - internal Enumerator(T[] records, int max, int index, int token) - { - this.records = records; - this.token = token; - this.max = max; - this.index = index; - } - - public int Current - { - get { return index; } - } - - public bool MoveNext() - { - while (index < max) - { - index++; - if (records[index].FilterKey == token) - { - return true; - } - } - return false; - } - } - - internal Enumerable Filter(int token) - { - return new Enumerable(this, token); - } - - protected void Sort() - { - ulong[] map = new ulong[rowCount]; - for (uint i = 0; i < map.Length; i++) - { - map[i] = ((ulong)records[i].SortKey << 32) | i; - } - Array.Sort(map); - T[] newRecords = new T[rowCount]; - for (int i = 0; i < map.Length; i++) - { - newRecords[i] = records[(int)map[i]]; - } - records = newRecords; - } - } - - sealed class ModuleTable : Table - { - internal const int Index = 0x00; - - internal struct Record - { - internal short Generation; - internal int Name; // -> StringHeap - internal int Mvid; // -> GuidHeap - internal int EncId; // -> GuidHeap - internal int EncBaseId; // -> GuidHeap - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Generation = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - records[i].Mvid = mr.ReadGuidIndex(); - records[i].EncId = mr.ReadGuidIndex(); - records[i].EncBaseId = mr.ReadGuidIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Generation); - mw.WriteStringIndex(records[i].Name); - mw.WriteGuidIndex(records[i].Mvid); - mw.WriteGuidIndex(records[i].EncId); - mw.WriteGuidIndex(records[i].EncBaseId); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteStringIndex() - .WriteGuidIndex() - .WriteGuidIndex() - .WriteGuidIndex() - .Value; - } - - internal void Add(short generation, int name, int mvid, int encid, int encbaseid) - { - Record record = new Record(); - record.Generation = generation; - record.Name = name; - record.Mvid = mvid; - record.EncId = encid; - record.EncBaseId = encbaseid; - AddRecord(record); - } - } - - sealed class TypeRefTable : Table - { - internal const int Index = 0x01; - - internal struct Record - { - internal int ResolutionScope; - internal int TypeName; - internal int TypeNameSpace; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].ResolutionScope = mr.ReadResolutionScope(); - records[i].TypeName = mr.ReadStringIndex(); - records[i].TypeNameSpace = mr.ReadStringIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteResolutionScope(records[i].ResolutionScope); - mw.WriteStringIndex(records[i].TypeName); - mw.WriteStringIndex(records[i].TypeNameSpace); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteResolutionScope() - .WriteStringIndex() - .WriteStringIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope); - } - } - } - - sealed class TypeDefTable : Table - { - internal const int Index = 0x02; - - internal struct Record - { - internal int Flags; - internal int TypeName; - internal int TypeNamespace; - internal int Extends; - internal int FieldList; - internal int MethodList; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt32(); - records[i].TypeName = mr.ReadStringIndex(); - records[i].TypeNamespace = mr.ReadStringIndex(); - records[i].Extends = mr.ReadTypeDefOrRef(); - records[i].FieldList = mr.ReadField(); - records[i].MethodList = mr.ReadMethodDef(); - } - } - - internal override void Write(MetadataWriter mw) - { - mw.ModuleBuilder.WriteTypeDefTable(mw); - } - - internal int AllocToken() - { - return 0x02000000 + AddVirtualRecord(); - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteStringIndex() - .WriteStringIndex() - .WriteTypeDefOrRef() - .WriteField() - .WriteMethodDef() - .Value; - } - } - - sealed class FieldPtrTable : Table - { - internal const int Index = 0x03; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadField(); - } - } - } - - sealed class FieldTable : Table - { - internal const int Index = 0x04; - - internal struct Record - { - internal short Flags; - internal int Name; - internal int Signature; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - records[i].Signature = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - mw.ModuleBuilder.WriteFieldTable(mw); - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteStringIndex() - .WriteBlobIndex() - .Value; - } - } - - sealed class MethodPtrTable : Table - { - internal const int Index = 0x05; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadMethodDef(); - } - } - } - - sealed class MethodDefTable : Table - { - internal const int Index = 0x06; - private int baseRVA; - - internal struct Record - { - internal int RVA; - internal short ImplFlags; - internal short Flags; - internal int Name; - internal int Signature; - internal int ParamList; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].RVA = mr.ReadInt32(); - records[i].ImplFlags = mr.ReadInt16(); - records[i].Flags = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - records[i].Signature = mr.ReadBlobIndex(); - records[i].ParamList = mr.ReadParam(); - } - } - - internal override void Write(MetadataWriter mw) - { - mw.ModuleBuilder.WriteMethodDefTable(baseRVA, mw); - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(8) - .WriteStringIndex() - .WriteBlobIndex() - .WriteParam() - .Value; - } - - internal void Fixup(TextSection code) - { - baseRVA = (int)code.MethodBodiesRVA; - } - } - - sealed class ParamPtrTable : Table - { - internal const int Index = 0x07; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadParam(); - } - } - } - - sealed class ParamTable : Table - { - internal const int Index = 0x08; - - internal struct Record - { - internal short Flags; - internal short Sequence; - internal int Name; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt16(); - records[i].Sequence = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - mw.ModuleBuilder.WriteParamTable(mw); - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteStringIndex() - .Value; - } - } - - sealed class InterfaceImplTable : SortedTable - { - internal const int Index = 0x09; - - internal struct Record : IRecord - { - internal int Class; - internal int Interface; - - int IRecord.SortKey - { - get { return Class; } - } - - int IRecord.FilterKey - { - get { return Class; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Class = mr.ReadTypeDef(); - records[i].Interface = mr.ReadTypeDefOrRef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteTypeDef(records[i].Class); - mw.WriteEncodedTypeDefOrRef(records[i].Interface); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteTypeDef() - .WriteTypeDefOrRef() - .Value; - } - - internal void Fixup() - { - for (int i = 0; i < rowCount; i++) - { - int token = records[i].Interface; - switch (token >> 24) - { - case 0: - break; - case TypeDefTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case TypeRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case TypeSpecTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - default: - throw new InvalidOperationException(); - } - records[i].Interface = token; - } - // LAMESPEC the CLI spec says that InterfaceImpl should be sorted by { Class, Interface }, - // but it appears to only be necessary to sort by Class (and csc emits InterfaceImpl records in - // source file order, so to be able to support round tripping, we need to retain ordering as well). - Sort(); - } - } - - sealed class MemberRefTable : Table - { - internal const int Index = 0x0A; - - internal struct Record - { - internal int Class; - internal int Name; - internal int Signature; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Class = mr.ReadMemberRefParent(); - records[i].Name = mr.ReadStringIndex(); - records[i].Signature = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteMemberRefParent(records[i].Class); - mw.WriteStringIndex(records[i].Name); - mw.WriteBlobIndex(records[i].Signature); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteMemberRefParent() - .WriteStringIndex() - .WriteBlobIndex() - .Value; - } - - internal int FindOrAddRecord(Record record) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i].Class == record.Class - && records[i].Name == record.Name - && records[i].Signature == record.Signature) - { - return i + 1; - } - } - return AddRecord(record); - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Class); - } - } - } - - sealed class ConstantTable : SortedTable - { - internal const int Index = 0x0B; - - internal struct Record : IRecord - { - internal short Type; - internal int Parent; - internal int Value; - - int IRecord.SortKey - { - get { return EncodeHasConstant(Parent); } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Type = mr.ReadInt16(); - records[i].Parent = mr.ReadHasConstant(); - records[i].Value = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Type); - mw.WriteHasConstant(records[i].Parent); - mw.WriteBlobIndex(records[i].Value); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteHasConstant() - .WriteBlobIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Parent); - } - Sort(); - } - - internal static int EncodeHasConstant(int token) - { - switch (token >> 24) - { - case FieldTable.Index: - return (token & 0xFFFFFF) << 2 | 0; - case ParamTable.Index: - return (token & 0xFFFFFF) << 2 | 1; - case PropertyTable.Index: - return (token & 0xFFFFFF) << 2 | 2; - default: - throw new InvalidOperationException(); - } - } - - internal object GetRawConstantValue(Module module, int parent) - { - foreach (int i in Filter(parent)) - { - ByteReader br = module.GetBlob(module.Constant.records[i].Value); - switch (module.Constant.records[i].Type) - { - // see ModuleBuilder.AddConstant for the encodings - case Signature.ELEMENT_TYPE_BOOLEAN: - return br.ReadByte() != 0; - case Signature.ELEMENT_TYPE_I1: - return br.ReadSByte(); - case Signature.ELEMENT_TYPE_I2: - return br.ReadInt16(); - case Signature.ELEMENT_TYPE_I4: - return br.ReadInt32(); - case Signature.ELEMENT_TYPE_I8: - return br.ReadInt64(); - case Signature.ELEMENT_TYPE_U1: - return br.ReadByte(); - case Signature.ELEMENT_TYPE_U2: - return br.ReadUInt16(); - case Signature.ELEMENT_TYPE_U4: - return br.ReadUInt32(); - case Signature.ELEMENT_TYPE_U8: - return br.ReadUInt64(); - case Signature.ELEMENT_TYPE_R4: - return br.ReadSingle(); - case Signature.ELEMENT_TYPE_R8: - return br.ReadDouble(); - case Signature.ELEMENT_TYPE_CHAR: - return br.ReadChar(); - case Signature.ELEMENT_TYPE_STRING: - { - char[] chars = new char[br.Length / 2]; - for (int j = 0; j < chars.Length; j++) - { - chars[j] = br.ReadChar(); - } - return new String(chars); - } - case Signature.ELEMENT_TYPE_CLASS: - if (br.ReadInt32() != 0) - { - throw new BadImageFormatException(); - } - return null; - default: - throw new BadImageFormatException(); - } - } - throw new InvalidOperationException(); - } - } - - sealed class CustomAttributeTable : SortedTable - { - internal const int Index = 0x0C; - - internal struct Record : IRecord - { - internal int Parent; - internal int Type; - internal int Value; - - int IRecord.SortKey - { - get { return EncodeHasCustomAttribute(Parent); } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Parent = mr.ReadHasCustomAttribute(); - records[i].Type = mr.ReadCustomAttributeType(); - records[i].Value = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteHasCustomAttribute(records[i].Parent); - mw.WriteCustomAttributeType(records[i].Type); - mw.WriteBlobIndex(records[i].Value); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteHasCustomAttribute() - .WriteCustomAttributeType() - .WriteBlobIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - int[] genericParamFixup = moduleBuilder.GenericParam.GetIndexFixup(); - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Type); - moduleBuilder.FixupPseudoToken(ref records[i].Parent); - if (records[i].Parent >> 24 == GenericParamTable.Index) - { - records[i].Parent = (GenericParamTable.Index << 24) + genericParamFixup[(records[i].Parent & 0xFFFFFF) - 1] + 1; - } - } - Sort(); - } - - internal static int EncodeHasCustomAttribute(int token) - { - switch (token >> 24) - { - case MethodDefTable.Index: - return (token & 0xFFFFFF) << 5 | 0; - case FieldTable.Index: - return (token & 0xFFFFFF) << 5 | 1; - case TypeRefTable.Index: - return (token & 0xFFFFFF) << 5 | 2; - case TypeDefTable.Index: - return (token & 0xFFFFFF) << 5 | 3; - case ParamTable.Index: - return (token & 0xFFFFFF) << 5 | 4; - case InterfaceImplTable.Index: - return (token & 0xFFFFFF) << 5 | 5; - case MemberRefTable.Index: - return (token & 0xFFFFFF) << 5 | 6; - case ModuleTable.Index: - return (token & 0xFFFFFF) << 5 | 7; - // Permission (8) table doesn't exist in the spec - case PropertyTable.Index: - return (token & 0xFFFFFF) << 5 | 9; - case EventTable.Index: - return (token & 0xFFFFFF) << 5 | 10; - case StandAloneSigTable.Index: - return (token & 0xFFFFFF) << 5 | 11; - case ModuleRefTable.Index: - return (token & 0xFFFFFF) << 5 | 12; - case TypeSpecTable.Index: - return (token & 0xFFFFFF) << 5 | 13; - case AssemblyTable.Index: - return (token & 0xFFFFFF) << 5 | 14; - case AssemblyRefTable.Index: - return (token & 0xFFFFFF) << 5 | 15; - case FileTable.Index: - return (token & 0xFFFFFF) << 5 | 16; - case ExportedTypeTable.Index: - return (token & 0xFFFFFF) << 5 | 17; - case ManifestResourceTable.Index: - return (token & 0xFFFFFF) << 5 | 18; - case GenericParamTable.Index: - return (token & 0xFFFFFF) << 5 | 19; - default: - throw new InvalidOperationException(); - } - } - } - - sealed class FieldMarshalTable : SortedTable - { - internal const int Index = 0x0D; - - internal struct Record : IRecord - { - internal int Parent; - internal int NativeType; - - int IRecord.SortKey - { - get { return EncodeHasFieldMarshal(Parent); } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Parent = mr.ReadHasFieldMarshal(); - records[i].NativeType = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteHasFieldMarshal(records[i].Parent); - mw.WriteBlobIndex(records[i].NativeType); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteHasFieldMarshal() - .WriteBlobIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - records[i].Parent = moduleBuilder.ResolvePseudoToken(records[i].Parent); - } - Sort(); - } - - internal static int EncodeHasFieldMarshal(int token) - { - switch (token >> 24) - { - case FieldTable.Index: - return (token & 0xFFFFFF) << 1 | 0; - case ParamTable.Index: - return (token & 0xFFFFFF) << 1 | 1; - default: - throw new InvalidOperationException(); - } - } - } - - sealed class DeclSecurityTable : SortedTable - { - internal const int Index = 0x0E; - - internal struct Record : IRecord - { - internal short Action; - internal int Parent; - internal int PermissionSet; - - int IRecord.SortKey - { - get { return Parent; } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Action = mr.ReadInt16(); - records[i].Parent = mr.ReadHasDeclSecurity(); - records[i].PermissionSet = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Action); - mw.WriteHasDeclSecurity(records[i].Parent); - mw.WriteBlobIndex(records[i].PermissionSet); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteHasDeclSecurity() - .WriteBlobIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - int token = records[i].Parent; - moduleBuilder.FixupPseudoToken(ref token); - // do the HasDeclSecurity encoding, so that we can sort the table - switch (token >> 24) - { - case TypeDefTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case MethodDefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case AssemblyTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - default: - throw new InvalidOperationException(); - } - records[i].Parent = token; - } - Sort(); - } - } - - sealed class ClassLayoutTable : SortedTable - { - internal const int Index = 0x0f; - - internal struct Record : IRecord - { - internal short PackingSize; - internal int ClassSize; - internal int Parent; - - int IRecord.SortKey - { - get { return Parent; } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].PackingSize = mr.ReadInt16(); - records[i].ClassSize = mr.ReadInt32(); - records[i].Parent = mr.ReadTypeDef(); - } - } - - internal override void Write(MetadataWriter mw) - { - Sort(); - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].PackingSize); - mw.Write(records[i].ClassSize); - mw.WriteTypeDef(records[i].Parent); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(6) - .WriteTypeDef() - .Value; - } - } - - sealed class FieldLayoutTable : SortedTable - { - internal const int Index = 0x10; - - internal struct Record : IRecord - { - internal int Offset; - internal int Field; - - int IRecord.SortKey - { - get { return Field; } - } - - int IRecord.FilterKey - { - get { return Field; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Offset = mr.ReadInt32(); - records[i].Field = mr.ReadField(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Offset); - mw.WriteField(records[i].Field); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteField() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - records[i].Field = moduleBuilder.ResolvePseudoToken(records[i].Field) & 0xFFFFFF; - } - Sort(); - } - } - - sealed class StandAloneSigTable : Table - { - internal const int Index = 0x11; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteBlobIndex(records[i]); - } - } - - protected override int GetRowSize(Table.RowSizeCalc rsc) - { - return rsc.WriteBlobIndex().Value; - } - - internal int FindOrAddRecord(int blob) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i] == blob) - { - return i + 1; - } - } - return AddRecord(blob); - } - } - - sealed class EventMapTable : SortedTable - { - internal const int Index = 0x12; - - internal struct Record : IRecord - { - internal int Parent; - internal int EventList; - - int IRecord.SortKey - { - get { return Parent; } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Parent = mr.ReadTypeDef(); - records[i].EventList = mr.ReadEvent(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteTypeDef(records[i].Parent); - mw.WriteEvent(records[i].EventList); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteTypeDef() - .WriteEvent() - .Value; - } - } - - sealed class EventPtrTable : Table - { - internal const int Index = 0x13; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadEvent(); - } - } - } - - sealed class EventTable : Table - { - internal const int Index = 0x14; - - internal struct Record - { - internal short EventFlags; - internal int Name; - internal int EventType; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].EventFlags = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - records[i].EventType = mr.ReadTypeDefOrRef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].EventFlags); - mw.WriteStringIndex(records[i].Name); - mw.WriteTypeDefOrRef(records[i].EventType); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteStringIndex() - .WriteTypeDefOrRef() - .Value; - } - } - - sealed class PropertyMapTable : SortedTable - { - internal const int Index = 0x15; - - internal struct Record : IRecord - { - internal int Parent; - internal int PropertyList; - - int IRecord.SortKey - { - get { return Parent; } - } - - int IRecord.FilterKey - { - get { return Parent; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Parent = mr.ReadTypeDef(); - records[i].PropertyList = mr.ReadProperty(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteTypeDef(records[i].Parent); - mw.WriteProperty(records[i].PropertyList); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteTypeDef() - .WriteProperty() - .Value; - } - } - - sealed class PropertyPtrTable : Table - { - internal const int Index = 0x16; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadProperty(); - } - } - } - - sealed class PropertyTable : Table - { - internal const int Index = 0x17; - - internal struct Record - { - internal short Flags; - internal int Name; - internal int Type; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt16(); - records[i].Name = mr.ReadStringIndex(); - records[i].Type = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Flags); - mw.WriteStringIndex(records[i].Name); - mw.WriteBlobIndex(records[i].Type); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteStringIndex() - .WriteBlobIndex() - .Value; - } - } - - sealed class MethodSemanticsTable : SortedTable - { - internal const int Index = 0x18; - - // semantics - internal const short Setter = 0x0001; - internal const short Getter = 0x0002; - internal const short Other = 0x0004; - internal const short AddOn = 0x0008; - internal const short RemoveOn = 0x0010; - internal const short Fire = 0x0020; - - internal struct Record : IRecord - { - internal short Semantics; - internal int Method; - internal int Association; - - int IRecord.SortKey - { - get { return Association; } - } - - int IRecord.FilterKey - { - get { return Association; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Semantics = mr.ReadInt16(); - records[i].Method = mr.ReadMethodDef(); - records[i].Association = mr.ReadHasSemantics(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Semantics); - mw.WriteMethodDef(records[i].Method); - mw.WriteHasSemantics(records[i].Association); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteMethodDef() - .WriteHasSemantics() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Method); - int token = records[i].Association; - // do the HasSemantics encoding, so that we can sort the table - switch (token >> 24) - { - case EventTable.Index: - token = (token & 0xFFFFFF) << 1 | 0; - break; - case PropertyTable.Index: - token = (token & 0xFFFFFF) << 1 | 1; - break; - default: - throw new InvalidOperationException(); - } - records[i].Association = token; - } - Sort(); - } - - internal MethodInfo GetMethod(Module module, int token, bool nonPublic, short semantics) - { - foreach (int i in Filter(token)) - { - if ((records[i].Semantics & semantics) != 0) - { - MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method); - if (nonPublic || method.IsPublic) - { - return (MethodInfo)method; - } - } - } - return null; - } - - internal MethodInfo[] GetMethods(Module module, int token, bool nonPublic, short semantics) - { - List methods = new List(); - foreach (int i in Filter(token)) - { - if ((records[i].Semantics & semantics) != 0) - { - MethodInfo method = (MethodInfo)module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method); - if (nonPublic || method.IsPublic) - { - methods.Add(method); - } - } - } - return methods.ToArray(); - } - - internal void ComputeFlags(Module module, int token, out bool isPublic, out bool isNonPrivate, out bool isStatic) - { - isPublic = false; - isNonPrivate = false; - isStatic = false; - foreach (int i in Filter(token)) - { - MethodBase method = module.ResolveMethod((MethodDefTable.Index << 24) + records[i].Method); - isPublic |= method.IsPublic; - isNonPrivate |= (method.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private; - isStatic |= method.IsStatic; - } - } - } - - sealed class MethodImplTable : SortedTable - { - internal const int Index = 0x19; - - internal struct Record : IRecord - { - internal int Class; - internal int MethodBody; - internal int MethodDeclaration; - - int IRecord.SortKey - { - get { return Class; } - } - - int IRecord.FilterKey - { - get { return Class; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Class = mr.ReadTypeDef(); - records[i].MethodBody = mr.ReadMethodDefOrRef(); - records[i].MethodDeclaration = mr.ReadMethodDefOrRef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteTypeDef(records[i].Class); - mw.WriteMethodDefOrRef(records[i].MethodBody); - mw.WriteMethodDefOrRef(records[i].MethodDeclaration); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteTypeDef() - .WriteMethodDefOrRef() - .WriteMethodDefOrRef() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].MethodBody); - moduleBuilder.FixupPseudoToken(ref records[i].MethodDeclaration); - } - Sort(); - } - } - - sealed class ModuleRefTable : Table - { - internal const int Index = 0x1A; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadStringIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteStringIndex(records[i]); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteStringIndex() - .Value; - } - - internal int FindOrAddRecord(int str) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i] == str) - { - return i + 1; - } - } - return AddRecord(str); - } - } - - sealed class TypeSpecTable : Table - { - internal const int Index = 0x1B; - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i] = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteBlobIndex(records[i]); - } - } - - protected override int GetRowSize(Table.RowSizeCalc rsc) - { - return rsc.WriteBlobIndex().Value; - } - } - - sealed class ImplMapTable : SortedTable - { - internal const int Index = 0x1C; - - internal struct Record : IRecord - { - internal short MappingFlags; - internal int MemberForwarded; - internal int ImportName; - internal int ImportScope; - - int IRecord.SortKey - { - get { return MemberForwarded; } - } - - int IRecord.FilterKey - { - get { return MemberForwarded; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].MappingFlags = mr.ReadInt16(); - records[i].MemberForwarded = mr.ReadMemberForwarded(); - records[i].ImportName = mr.ReadStringIndex(); - records[i].ImportScope = mr.ReadModuleRef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].MappingFlags); - mw.WriteMemberForwarded(records[i].MemberForwarded); - mw.WriteStringIndex(records[i].ImportName); - mw.WriteModuleRef(records[i].ImportScope); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(2) - .WriteMemberForwarded() - .WriteStringIndex() - .WriteModuleRef() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].MemberForwarded); - } - Sort(); - } - } - - sealed class FieldRVATable : SortedTable - { - internal const int Index = 0x1D; - - internal struct Record : IRecord - { - internal int RVA; // we set the high bit to signify that the RVA is in the CIL stream (instead of .sdata) - internal int Field; - - int IRecord.SortKey - { - get { return Field; } - } - - int IRecord.FilterKey - { - get { return Field; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].RVA = mr.ReadInt32(); - records[i].Field = mr.ReadField(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].RVA); - mw.WriteField(records[i].Field); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteField() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder, int sdataRVA, int cilRVA) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i].RVA < 0) - { - records[i].RVA = (records[i].RVA & 0x7fffffff) + cilRVA; - } - else - { - records[i].RVA += sdataRVA; - } - moduleBuilder.FixupPseudoToken(ref records[i].Field); - } - Sort(); - } - } - - sealed class AssemblyTable : Table - { - internal const int Index = 0x20; - - internal struct Record - { - internal int HashAlgId; - internal ushort MajorVersion; - internal ushort MinorVersion; - internal ushort BuildNumber; - internal ushort RevisionNumber; - internal int Flags; - internal int PublicKey; - internal int Name; - internal int Culture; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].HashAlgId = mr.ReadInt32(); - records[i].MajorVersion = mr.ReadUInt16(); - records[i].MinorVersion = mr.ReadUInt16(); - records[i].BuildNumber = mr.ReadUInt16(); - records[i].RevisionNumber = mr.ReadUInt16(); - records[i].Flags = mr.ReadInt32(); - records[i].PublicKey = mr.ReadBlobIndex(); - records[i].Name = mr.ReadStringIndex(); - records[i].Culture = mr.ReadStringIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].HashAlgId); - mw.Write(records[i].MajorVersion); - mw.Write(records[i].MinorVersion); - mw.Write(records[i].BuildNumber); - mw.Write(records[i].RevisionNumber); - mw.Write(records[i].Flags); - mw.WriteBlobIndex(records[i].PublicKey); - mw.WriteStringIndex(records[i].Name); - mw.WriteStringIndex(records[i].Culture); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(16) - .WriteBlobIndex() - .WriteStringIndex() - .WriteStringIndex() - .Value; - } - } - - sealed class AssemblyRefTable : Table - { - internal const int Index = 0x23; - - internal struct Record - { - internal ushort MajorVersion; - internal ushort MinorVersion; - internal ushort BuildNumber; - internal ushort RevisionNumber; - internal int Flags; - internal int PublicKeyOrToken; - internal int Name; - internal int Culture; - internal int HashValue; - } - - internal int FindOrAddRecord(Record rec) - { - for (int i = 0; i < rowCount; i++) - { - // note that we ignore HashValue here! - if (records[i].Name == rec.Name - && records[i].MajorVersion == rec.MajorVersion - && records[i].MinorVersion == rec.MinorVersion - && records[i].BuildNumber == rec.BuildNumber - && records[i].RevisionNumber == rec.RevisionNumber - && records[i].Flags == rec.Flags - && records[i].PublicKeyOrToken == rec.PublicKeyOrToken - && records[i].Culture == rec.Culture - ) - { - return i + 1; - } - } - return AddRecord(rec); - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].MajorVersion = mr.ReadUInt16(); - records[i].MinorVersion = mr.ReadUInt16(); - records[i].BuildNumber = mr.ReadUInt16(); - records[i].RevisionNumber = mr.ReadUInt16(); - records[i].Flags = mr.ReadInt32(); - records[i].PublicKeyOrToken = mr.ReadBlobIndex(); - records[i].Name = mr.ReadStringIndex(); - records[i].Culture = mr.ReadStringIndex(); - records[i].HashValue = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].MajorVersion); - mw.Write(records[i].MinorVersion); - mw.Write(records[i].BuildNumber); - mw.Write(records[i].RevisionNumber); - mw.Write(records[i].Flags); - mw.WriteBlobIndex(records[i].PublicKeyOrToken); - mw.WriteStringIndex(records[i].Name); - mw.WriteStringIndex(records[i].Culture); - mw.WriteBlobIndex(records[i].HashValue); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(12) - .WriteBlobIndex() - .WriteStringIndex() - .WriteStringIndex() - .WriteBlobIndex() - .Value; - } - } - - sealed class FileTable : Table - { - internal const int Index = 0x26; - - internal struct Record - { - internal int Flags; - internal int Name; - internal int HashValue; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt32(); - records[i].Name = mr.ReadStringIndex(); - records[i].HashValue = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Flags); - mw.WriteStringIndex(records[i].Name); - mw.WriteBlobIndex(records[i].HashValue); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteStringIndex() - .WriteBlobIndex() - .Value; - } - } - - sealed class ExportedTypeTable : Table - { - internal const int Index = 0x27; - - internal struct Record - { - internal int Flags; - internal int TypeDefId; - internal int TypeName; - internal int TypeNamespace; - internal int Implementation; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Flags = mr.ReadInt32(); - records[i].TypeDefId = mr.ReadInt32(); - records[i].TypeName = mr.ReadStringIndex(); - records[i].TypeNamespace = mr.ReadStringIndex(); - records[i].Implementation = mr.ReadImplementation(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Flags); - mw.Write(records[i].TypeDefId); - mw.WriteStringIndex(records[i].TypeName); - mw.WriteStringIndex(records[i].TypeNamespace); - mw.WriteImplementation(records[i].Implementation); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(8) - .WriteStringIndex() - .WriteStringIndex() - .WriteImplementation() - .Value; - } - - internal int FindOrAddRecord(Record rec) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i].Implementation == rec.Implementation - && records[i].TypeName == rec.TypeName - && records[i].TypeNamespace == rec.TypeNamespace) - { - return i + 1; - } - } - return AddRecord(rec); - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Implementation); - } - } - } - - sealed class ManifestResourceTable : Table - { - internal const int Index = 0x28; - - internal struct Record - { - internal int Offset; - internal int Flags; - internal int Name; - internal int Implementation; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Offset = mr.ReadInt32(); - records[i].Flags = mr.ReadInt32(); - records[i].Name = mr.ReadStringIndex(); - records[i].Implementation = mr.ReadImplementation(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Offset); - mw.Write(records[i].Flags); - mw.WriteStringIndex(records[i].Name); - mw.WriteImplementation(records[i].Implementation); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(8) - .WriteStringIndex() - .WriteImplementation() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Implementation); - } - } - } - - sealed class NestedClassTable : SortedTable - { - internal const int Index = 0x29; - - internal struct Record : IRecord - { - internal int NestedClass; - internal int EnclosingClass; - - int IRecord.SortKey - { - get { return NestedClass; } - } - - int IRecord.FilterKey - { - get { return NestedClass; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].NestedClass = mr.ReadTypeDef(); - records[i].EnclosingClass = mr.ReadTypeDef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteTypeDef(records[i].NestedClass); - mw.WriteTypeDef(records[i].EnclosingClass); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteTypeDef() - .WriteTypeDef() - .Value; - } - - internal List GetNestedClasses(int enclosingClass) - { - List nestedClasses = new List(); - for (int i = 0; i < rowCount; i++) - { - if (records[i].EnclosingClass == enclosingClass) - { - nestedClasses.Add(records[i].NestedClass); - } - } - return nestedClasses; - } - } - - sealed class GenericParamTable : SortedTable, IComparer - { - internal const int Index = 0x2A; - - internal struct Record : IRecord - { - internal short Number; - internal short Flags; - internal int Owner; - internal int Name; - // not part of the table, we use it to be able to fixup the GenericParamConstraint table - internal int unsortedIndex; - - int IRecord.SortKey - { - get { return Owner; } - } - - int IRecord.FilterKey - { - get { return Owner; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Number = mr.ReadInt16(); - records[i].Flags = mr.ReadInt16(); - records[i].Owner = mr.ReadTypeOrMethodDef(); - records[i].Name = mr.ReadStringIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.Write(records[i].Number); - mw.Write(records[i].Flags); - mw.WriteTypeOrMethodDef(records[i].Owner); - mw.WriteStringIndex(records[i].Name); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .AddFixed(4) - .WriteTypeOrMethodDef() - .WriteStringIndex() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - int token = records[i].Owner; - moduleBuilder.FixupPseudoToken(ref token); - // do the TypeOrMethodDef encoding, so that we can sort the table - switch (token >> 24) - { - case TypeDefTable.Index: - records[i].Owner = (token & 0xFFFFFF) << 1 | 0; - break; - case MethodDefTable.Index: - records[i].Owner = (token & 0xFFFFFF) << 1 | 1; - break; - default: - throw new InvalidOperationException(); - } - records[i].unsortedIndex = i; - } - // FXBUG the unnecessary (IComparer) cast is a workaround for a .NET 2.0 C# compiler bug - Array.Sort(records, 0, rowCount, (IComparer)this); - } - - int IComparer.Compare(Record x, Record y) - { - if (x.Owner == y.Owner) - { - return x.Number == y.Number ? 0 : (x.Number > y.Number ? 1 : -1); - } - return x.Owner > y.Owner ? 1 : -1; - } - - internal void PatchAttribute(int token, GenericParameterAttributes genericParameterAttributes) - { - records[(token & 0xFFFFFF) - 1].Flags = (short)genericParameterAttributes; - } - - internal int[] GetIndexFixup() - { - int[] array = new int[rowCount]; - for (int i = 0; i < rowCount; i++) - { - array[records[i].unsortedIndex] = i; - } - return array; - } - - internal int FindFirstByOwner(int token) - { - foreach (int i in Filter(token)) - { - return i; - } - return -1; - } - } - - sealed class MethodSpecTable : Table - { - internal const int Index = 0x2B; - - internal struct Record - { - internal int Method; - internal int Instantiation; - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Method = mr.ReadMethodDefOrRef(); - records[i].Instantiation = mr.ReadBlobIndex(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteMethodDefOrRef(records[i].Method); - mw.WriteBlobIndex(records[i].Instantiation); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteMethodDefOrRef() - .WriteBlobIndex() - .Value; - } - - internal int FindOrAddRecord(Record record) - { - for (int i = 0; i < rowCount; i++) - { - if (records[i].Method == record.Method - && records[i].Instantiation == record.Instantiation) - { - return i + 1; - } - } - return AddRecord(record); - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - for (int i = 0; i < rowCount; i++) - { - moduleBuilder.FixupPseudoToken(ref records[i].Method); - } - } - } - - sealed class GenericParamConstraintTable : SortedTable - { - internal const int Index = 0x2C; - - internal struct Record : IRecord - { - internal int Owner; - internal int Constraint; - - int IRecord.SortKey - { - get { return Owner; } - } - - int IRecord.FilterKey - { - get { return Owner; } - } - } - - internal override void Read(MetadataReader mr) - { - for (int i = 0; i < records.Length; i++) - { - records[i].Owner = mr.ReadGenericParam(); - records[i].Constraint = mr.ReadTypeDefOrRef(); - } - } - - internal override void Write(MetadataWriter mw) - { - for (int i = 0; i < rowCount; i++) - { - mw.WriteGenericParam(records[i].Owner); - mw.WriteTypeDefOrRef(records[i].Constraint); - } - } - - protected override int GetRowSize(RowSizeCalc rsc) - { - return rsc - .WriteGenericParam() - .WriteTypeDefOrRef() - .Value; - } - - internal void Fixup(ModuleBuilder moduleBuilder) - { - int[] fixups = moduleBuilder.GenericParam.GetIndexFixup(); - for (int i = 0; i < rowCount; i++) - { - records[i].Owner = fixups[records[i].Owner - 1] + 1; - } - Sort(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/MethodBase.cs b/mcs/class/IKVM.Reflection/MethodBase.cs deleted file mode 100644 index 1bf10e2c420..00000000000 --- a/mcs/class/IKVM.Reflection/MethodBase.cs +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -namespace IKVM.Reflection -{ - public abstract class MethodBase : MemberInfo - { - // prevent external subclasses - internal MethodBase() - { - } - - internal abstract MethodSignature MethodSignature { get; } - internal abstract int ParameterCount { get; } - public abstract ParameterInfo[] GetParameters(); - public abstract MethodAttributes Attributes { get; } - public abstract MethodImplAttributes GetMethodImplementationFlags(); - public abstract MethodBody GetMethodBody(); - public abstract CallingConventions CallingConvention { get; } - public abstract int __MethodRVA { get; } - - public bool IsConstructor - { - get - { - if ((this.Attributes & MethodAttributes.RTSpecialName) != 0) - { - string name = this.Name; - return name == ConstructorInfo.ConstructorName || name == ConstructorInfo.TypeConstructorName; - } - return false; - } - } - - public bool IsStatic - { - get { return (Attributes & MethodAttributes.Static) != 0; } - } - - public bool IsVirtual - { - get { return (Attributes & MethodAttributes.Virtual) != 0; } - } - - public bool IsAbstract - { - get { return (Attributes & MethodAttributes.Abstract) != 0; } - } - - public bool IsFinal - { - get { return (Attributes & MethodAttributes.Final) != 0; } - } - - public bool IsPublic - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } - } - - public bool IsFamily - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } - } - - public bool IsFamilyOrAssembly - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } - } - - public bool IsAssembly - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } - } - - public bool IsFamilyAndAssembly - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } - } - - public bool IsPrivate - { - get { return (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } - } - - public bool IsSpecialName - { - get { return (Attributes & MethodAttributes.SpecialName) != 0; } - } - - public bool IsHideBySig - { - get { return (Attributes & MethodAttributes.HideBySig) != 0; } - } - - public virtual Type[] GetGenericArguments() - { - return Type.EmptyTypes; - } - - public virtual bool IsGenericMethod - { - get { return false; } - } - - public virtual bool IsGenericMethodDefinition - { - get { return false; } - } - - public virtual bool ContainsGenericParameters - { - get { return IsGenericMethodDefinition; } - } - - public virtual MethodBase __GetMethodOnTypeDefinition() - { - return this; - } - - // This goes to the (uninstantiated) MethodInfo on the (uninstantiated) Type. For constructors - // it also has the effect of removing the ConstructorInfo wrapper and returning the underlying MethodInfo. - internal abstract MethodInfo GetMethodOnTypeDefinition(); - - internal abstract int ImportTo(Emit.ModuleBuilder module); - - internal abstract MethodBase BindTypeParameters(Type type); - - internal sealed override bool BindingFlagsMatch(BindingFlags flags) - { - return BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static, BindingFlags.Instance); - } - - internal sealed override bool BindingFlagsMatchInherited(BindingFlags flags) - { - return (Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private - && BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance); - } - } -} diff --git a/mcs/class/IKVM.Reflection/MethodBody.cs b/mcs/class/IKVM.Reflection/MethodBody.cs deleted file mode 100644 index fc26f6fdad9..00000000000 --- a/mcs/class/IKVM.Reflection/MethodBody.cs +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using IKVM.Reflection.Reader; -using System.IO; - -namespace IKVM.Reflection -{ - public sealed class MethodBody - { - private readonly IList exceptionClauses; - private readonly IList locals; - private readonly bool initLocals; - private readonly int maxStack; - private readonly int localVarSigTok; - private byte[] body; - - internal MethodBody(ModuleReader module, int rva, IGenericContext context) - { - const byte CorILMethod_TinyFormat = 0x02; - const byte CorILMethod_FatFormat = 0x03; - const byte CorILMethod_MoreSects = 0x08; - const byte CorILMethod_InitLocals = 0x10; - const byte CorILMethod_Sect_EHTable = 0x01; - const byte CorILMethod_Sect_FatFormat = 0x40; - const byte CorILMethod_Sect_MoreSects = 0x80; - - List exceptionClauses = new List(); - List locals = new List(); - module.SeekRVA(rva); - BinaryReader br = new BinaryReader(module.stream); - byte b = br.ReadByte(); - if ((b & 3) == CorILMethod_TinyFormat) - { - initLocals = true; - body = br.ReadBytes(b >> 2); - maxStack = 8; - } - else if ((b & 3) == CorILMethod_FatFormat) - { - initLocals = (b & CorILMethod_InitLocals) != 0; - short flagsAndSize = (short)(b | (br.ReadByte() << 8)); - if ((flagsAndSize >> 12) != 3) - { - throw new BadImageFormatException("Fat format method header size should be 3"); - } - maxStack = br.ReadUInt16(); - int codeLength = br.ReadInt32(); - localVarSigTok = br.ReadInt32(); - body = br.ReadBytes(codeLength); - if ((b & CorILMethod_MoreSects) != 0) - { - module.stream.Position = (module.stream.Position + 3) & ~3; - int hdr = br.ReadInt32(); - if ((hdr & CorILMethod_Sect_MoreSects) != 0 || (hdr & CorILMethod_Sect_EHTable) == 0) - { - throw new NotImplementedException(); - } - else if ((hdr & CorILMethod_Sect_FatFormat) != 0) - { - int count = ComputeExceptionCount((hdr >> 8) & 0xFFFFFF, 24); - for (int i = 0; i < count; i++) - { - int flags = br.ReadInt32(); - int tryOffset = br.ReadInt32(); - int tryLength = br.ReadInt32(); - int handlerOffset = br.ReadInt32(); - int handlerLength = br.ReadInt32(); - int classTokenOrFilterOffset = br.ReadInt32(); - exceptionClauses.Add(new ExceptionHandlingClause(module, flags, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset, context)); - } - } - else - { - int count = ComputeExceptionCount((hdr >> 8) & 0xFF, 12); - for (int i = 0; i < count; i++) - { - int flags = br.ReadUInt16(); - int tryOffset = br.ReadUInt16(); - int tryLength = br.ReadByte(); - int handlerOffset = br.ReadUInt16(); - int handlerLength = br.ReadByte(); - int classTokenOrFilterOffset = br.ReadInt32(); - exceptionClauses.Add(new ExceptionHandlingClause(module, flags, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset, context)); - } - } - } - if (localVarSigTok != 0) - { - ByteReader sig = module.GetStandAloneSig((localVarSigTok & 0xFFFFFF) - 1); - Signature.ReadLocalVarSig(module, sig, context, locals); - } - } - else - { - throw new BadImageFormatException(); - } - this.exceptionClauses = exceptionClauses.AsReadOnly(); - this.locals = locals.AsReadOnly(); - } - - private static int ComputeExceptionCount(int size, int itemLength) - { - // LAMESPEC according to the spec, the count should be calculated as "(size - 4) / itemLength", - // FXBUG but to workaround a VB compiler bug that specifies the size incorrectly, - // we do a truncating division instead. - return size / itemLength; - } - - public IList ExceptionHandlingClauses - { - get { return exceptionClauses; } - } - - public bool InitLocals - { - get { return initLocals; } - } - - public IList LocalVariables - { - get { return locals; } - } - - public byte[] GetILAsByteArray() - { - return body; - } - - public int LocalSignatureMetadataToken - { - get { return localVarSigTok; } - } - - public int MaxStackSize - { - get { return maxStack; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/MethodImplMap.cs b/mcs/class/IKVM.Reflection/MethodImplMap.cs deleted file mode 100644 index bab829f60c9..00000000000 --- a/mcs/class/IKVM.Reflection/MethodImplMap.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ - public struct __MethodImplMap - { - public Type TargetType; - public MethodInfo[] MethodBodies; - public MethodInfo[][] MethodDeclarations; - } -} diff --git a/mcs/class/IKVM.Reflection/MethodInfo.cs b/mcs/class/IKVM.Reflection/MethodInfo.cs deleted file mode 100644 index 40ca321c7e6..00000000000 --- a/mcs/class/IKVM.Reflection/MethodInfo.cs +++ /dev/null @@ -1,403 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace IKVM.Reflection -{ - public abstract class MethodInfo : MethodBase, IGenericContext, IGenericBinder - { - // prevent external subclasses - internal MethodInfo() - { - } - - public sealed override MemberTypes MemberType - { - get { return MemberTypes.Method; } - } - - public abstract Type ReturnType { get; } - public abstract ParameterInfo ReturnParameter { get; } - - public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - throw new NotSupportedException(this.GetType().FullName); - } - - public virtual MethodInfo GetGenericMethodDefinition() - { - throw new NotSupportedException(this.GetType().FullName); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - sb.Append(this.ReturnType.Name).Append(' ').Append(this.Name); - string sep; - if (this.IsGenericMethod) - { - sb.Append('['); - sep = ""; - foreach (Type arg in GetGenericArguments()) - { - sb.Append(sep).Append(arg); - sep = ", "; - } - sb.Append(']'); - } - sb.Append('('); - sep = ""; - foreach (ParameterInfo arg in GetParameters()) - { - sb.Append(sep).Append(arg.ParameterType); - sep = ", "; - } - sb.Append(')'); - return sb.ToString(); - } - - internal bool IsNewSlot - { - get { return (this.Attributes & MethodAttributes.NewSlot) != 0; } - } - - public MethodInfo GetBaseDefinition() - { - MethodInfo match = this; - if (match.IsVirtual) - { - for (Type type = this.DeclaringType.BaseType; type != null && !match.IsNewSlot; type = type.BaseType) - { - MethodInfo method = type.FindMethod(this.Name, this.MethodSignature) as MethodInfo; - if (method != null && method.IsVirtual) - { - match = method; - } - } - } - return match; - } - - public virtual MethodInfo[] __GetMethodImpls() - { - throw new NotSupportedException(); - } - - public bool __TryGetImplMap(out ImplMapFlags mappingFlags, out string importName, out string importScope) - { - Module module = this.Module; - foreach (int i in module.ImplMap.Filter(GetCurrentToken())) - { - mappingFlags = (ImplMapFlags)(ushort)module.ImplMap.records[i].MappingFlags; - importName = module.GetString(module.ImplMap.records[i].ImportName); - importScope = module.GetString(module.ModuleRef.records[(module.ImplMap.records[i].ImportScope & 0xFFFFFF) - 1]); - return true; - } - mappingFlags = 0; - importName = null; - importScope = null; - return false; - } - - public ConstructorInfo __AsConstructorInfo() - { - return new ConstructorInfoImpl(this); - } - - Type IGenericContext.GetGenericTypeArgument(int index) - { - return this.DeclaringType.GetGenericTypeArgument(index); - } - - Type IGenericContext.GetGenericMethodArgument(int index) - { - return GetGenericMethodArgument(index); - } - - internal virtual Type GetGenericMethodArgument(int index) - { - throw new InvalidOperationException(); - } - - internal virtual int GetGenericMethodArgumentCount() - { - throw new InvalidOperationException(); - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return this; - } - - Type IGenericBinder.BindTypeParameter(Type type) - { - return this.DeclaringType.GetGenericTypeArgument(type.GenericParameterPosition); - } - - Type IGenericBinder.BindMethodParameter(Type type) - { - return GetGenericMethodArgument(type.GenericParameterPosition); - } - - internal override MethodBase BindTypeParameters(Type type) - { - return new GenericMethodInstance(this.DeclaringType.BindTypeParameters(type), this, null); - } - - // This method is used by ILGenerator and exists to allow ArrayMethod to override it, - // because ArrayMethod doesn't have a working MethodAttributes property, so it needs - // to base the result of this on the CallingConvention. - internal virtual bool HasThis - { - get { return !IsStatic; } - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - return new MethodInfoWithReflectedType(type, this); - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - Module module = this.Module; - List list = new List(); - if ((this.Attributes & MethodAttributes.PinvokeImpl) != 0 - && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_DllImportAttribute))) - { - ImplMapFlags flags; - string importName; - string importScope; - if (__TryGetImplMap(out flags, out importName, out importScope)) - { - list.Add(CustomAttributeData.CreateDllImportPseudoCustomAttribute(module, flags, importName, importScope, GetMethodImplementationFlags())); - } - } - if ((GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0 - && (attributeType == null || attributeType.IsAssignableFrom(module.universe.System_Runtime_InteropServices_PreserveSigAttribute))) - { - list.Add(CustomAttributeData.CreatePreserveSigPseudoCustomAttribute(module)); - } - return list; - } - } - - sealed class MethodInfoWithReflectedType : MethodInfo - { - private readonly Type reflectedType; - private readonly MethodInfo method; - - internal MethodInfoWithReflectedType(Type reflectedType, MethodInfo method) - { - Debug.Assert(reflectedType != method.DeclaringType); - this.reflectedType = reflectedType; - this.method = method; - } - - public override bool Equals(object obj) - { - MethodInfoWithReflectedType other = obj as MethodInfoWithReflectedType; - return other != null - && other.reflectedType == reflectedType - && other.method == method; - } - - public override int GetHashCode() - { - return reflectedType.GetHashCode() ^ method.GetHashCode(); - } - - internal override MethodSignature MethodSignature - { - get { return method.MethodSignature; } - } - - internal override int ParameterCount - { - get { return method.ParameterCount; } - } - - public override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameters = method.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoWrapper(this, parameters[i]); - } - return parameters; - } - - public override MethodAttributes Attributes - { - get { return method.Attributes; } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return method.GetMethodImplementationFlags(); - } - - public override MethodBody GetMethodBody() - { - return method.GetMethodBody(); - } - - public override CallingConventions CallingConvention - { - get { return method.CallingConvention; } - } - - public override int __MethodRVA - { - get { return method.__MethodRVA; } - } - - public override Type ReturnType - { - get { return method.ReturnType; } - } - - public override ParameterInfo ReturnParameter - { - get { return new ParameterInfoWrapper(this, method.ReturnParameter); } - } - - public override MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - return SetReflectedType(method.MakeGenericMethod(typeArguments), reflectedType); - } - - public override MethodInfo GetGenericMethodDefinition() - { - return method.GetGenericMethodDefinition(); - } - - public override string ToString() - { - return method.ToString(); - } - - public override MethodInfo[] __GetMethodImpls() - { - return method.__GetMethodImpls(); - } - - internal override Type GetGenericMethodArgument(int index) - { - return method.GetGenericMethodArgument(index); - } - - internal override int GetGenericMethodArgumentCount() - { - return method.GetGenericMethodArgumentCount(); - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return method.GetMethodOnTypeDefinition(); - } - - internal override bool HasThis - { - get { return method.HasThis; } - } - - public override Module Module - { - get { return method.Module; } - } - - public override Type DeclaringType - { - get { return method.DeclaringType; } - } - - public override Type ReflectedType - { - get { return reflectedType; } - } - - public override string Name - { - get { return method.Name; } - } - - internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module) - { - return method.ImportTo(module); - } - - public override MethodBase __GetMethodOnTypeDefinition() - { - return method.__GetMethodOnTypeDefinition(); - } - - public override bool __IsMissing - { - get { return method.__IsMissing; } - } - - internal override MethodBase BindTypeParameters(Type type) - { - return method.BindTypeParameters(type); - } - - public override bool ContainsGenericParameters - { - get { return method.ContainsGenericParameters; } - } - - public override Type[] GetGenericArguments() - { - return method.GetGenericArguments(); - } - - public override bool IsGenericMethod - { - get { return method.IsGenericMethod; } - } - - public override bool IsGenericMethodDefinition - { - get { return method.IsGenericMethodDefinition; } - } - - public override int MetadataToken - { - get { return method.MetadataToken; } - } - - internal override int GetCurrentToken() - { - return method.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return method.IsBaked; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/MethodSignature.cs b/mcs/class/IKVM.Reflection/MethodSignature.cs deleted file mode 100644 index 76c9cb505b0..00000000000 --- a/mcs/class/IKVM.Reflection/MethodSignature.cs +++ /dev/null @@ -1,487 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection -{ - sealed class MethodSignature : Signature - { - private readonly Type returnType; - private readonly Type[] parameterTypes; - private readonly PackedCustomModifiers modifiers; - private readonly CallingConventions callingConvention; - private readonly int genericParamCount; - - internal MethodSignature(Type returnType, Type[] parameterTypes, PackedCustomModifiers modifiers, CallingConventions callingConvention, int genericParamCount) - { - this.returnType = returnType; - this.parameterTypes = parameterTypes; - this.modifiers = modifiers; - this.callingConvention = callingConvention; - this.genericParamCount = genericParamCount; - } - - public override bool Equals(object obj) - { - MethodSignature other = obj as MethodSignature; - return other != null - && other.callingConvention == callingConvention - && other.genericParamCount == genericParamCount - && other.returnType.Equals(returnType) - && Util.ArrayEquals(other.parameterTypes, parameterTypes) - && other.modifiers.Equals(modifiers); - } - - public override int GetHashCode() - { - return genericParamCount ^ 77 * (int)callingConvention - ^ 3 * returnType.GetHashCode() - ^ Util.GetHashCode(parameterTypes) * 5 - ^ modifiers.GetHashCode() * 55; - } - - private sealed class UnboundGenericMethodContext : IGenericContext - { - private readonly IGenericContext original; - - internal UnboundGenericMethodContext(IGenericContext original) - { - this.original = original; - } - - public Type GetGenericTypeArgument(int index) - { - return original.GetGenericTypeArgument(index); - } - - public Type GetGenericMethodArgument(int index) - { - return UnboundGenericMethodParameter.Make(index); - } - } - - internal static MethodSignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context) - { - CallingConventions callingConvention; - int genericParamCount; - Type returnType; - Type[] parameterTypes; - byte flags = br.ReadByte(); - switch (flags & 7) - { - case DEFAULT: - callingConvention = CallingConventions.Standard; - break; - case VARARG: - callingConvention = CallingConventions.VarArgs; - break; - default: - throw new BadImageFormatException(); - } - if ((flags & HASTHIS) != 0) - { - callingConvention |= CallingConventions.HasThis; - } - if ((flags & EXPLICITTHIS) != 0) - { - callingConvention |= CallingConventions.ExplicitThis; - } - genericParamCount = 0; - if ((flags & GENERIC) != 0) - { - genericParamCount = br.ReadCompressedInt(); - context = new UnboundGenericMethodContext(context); - } - int paramCount = br.ReadCompressedInt(); - CustomModifiers[] modifiers = null; - PackedCustomModifiers.Pack(ref modifiers, 0, CustomModifiers.Read(module, br, context), paramCount + 1); - returnType = ReadRetType(module, br, context); - parameterTypes = new Type[paramCount]; - for (int i = 0; i < parameterTypes.Length; i++) - { - if ((callingConvention & CallingConventions.VarArgs) != 0 && br.PeekByte() == SENTINEL) - { - Array.Resize(ref parameterTypes, i); - if (modifiers != null) - { - Array.Resize(ref modifiers, i + 1); - } - break; - } - PackedCustomModifiers.Pack(ref modifiers, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1); - parameterTypes[i] = ReadParam(module, br, context); - } - return new MethodSignature(returnType, parameterTypes, PackedCustomModifiers.Wrap(modifiers), callingConvention, genericParamCount); - } - - internal static __StandAloneMethodSig ReadStandAloneMethodSig(ModuleReader module, ByteReader br, IGenericContext context) - { - CallingConventions callingConvention = 0; - System.Runtime.InteropServices.CallingConvention unmanagedCallingConvention = 0; - bool unmanaged; - byte flags = br.ReadByte(); - switch (flags & 7) - { - case DEFAULT: - callingConvention = CallingConventions.Standard; - unmanaged = false; - break; - case 0x01: // C - unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl; - unmanaged = true; - break; - case 0x02: // STDCALL - unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall; - unmanaged = true; - break; - case 0x03: // THISCALL - unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.ThisCall; - unmanaged = true; - break; - case 0x04: // FASTCALL - unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.FastCall; - unmanaged = true; - break; - case VARARG: - callingConvention = CallingConventions.VarArgs; - unmanaged = false; - break; - default: - throw new BadImageFormatException(); - } - if ((flags & HASTHIS) != 0) - { - callingConvention |= CallingConventions.HasThis; - } - if ((flags & EXPLICITTHIS) != 0) - { - callingConvention |= CallingConventions.ExplicitThis; - } - if ((flags & GENERIC) != 0) - { - throw new BadImageFormatException(); - } - int paramCount = br.ReadCompressedInt(); - CustomModifiers[] customModifiers = null; - PackedCustomModifiers.Pack(ref customModifiers, 0, CustomModifiers.Read(module, br, context), paramCount + 1); - Type returnType = ReadRetType(module, br, context); - List parameterTypes = new List(); - List optionalParameterTypes = new List(); - List curr = parameterTypes; - for (int i = 0; i < paramCount; i++) - { - if (br.PeekByte() == SENTINEL) - { - br.ReadByte(); - curr = optionalParameterTypes; - } - PackedCustomModifiers.Pack(ref customModifiers, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1); - curr.Add(ReadParam(module, br, context)); - } - return new __StandAloneMethodSig(unmanaged, unmanagedCallingConvention, callingConvention, returnType, parameterTypes.ToArray(), optionalParameterTypes.ToArray(), PackedCustomModifiers.Wrap(customModifiers)); - } - - internal int GetParameterCount() - { - return parameterTypes.Length; - } - - internal Type GetParameterType(int index) - { - return parameterTypes[index]; - } - - internal Type GetReturnType(IGenericBinder binder) - { - return returnType.BindTypeParameters(binder); - } - - internal CustomModifiers GetReturnTypeCustomModifiers(IGenericBinder binder) - { - return modifiers.GetReturnTypeCustomModifiers().Bind(binder); - } - - internal Type GetParameterType(IGenericBinder binder, int index) - { - return parameterTypes[index].BindTypeParameters(binder); - } - - internal CustomModifiers GetParameterCustomModifiers(IGenericBinder binder, int index) - { - return modifiers.GetParameterCustomModifiers(index).Bind(binder); - } - - internal CallingConventions CallingConvention - { - get { return callingConvention; } - } - - internal int GenericParameterCount - { - get { return genericParamCount; } - } - - private sealed class Binder : IGenericBinder - { - private readonly Type declaringType; - private readonly Type[] methodArgs; - - internal Binder(Type declaringType, Type[] methodArgs) - { - this.declaringType = declaringType; - this.methodArgs = methodArgs; - } - - public Type BindTypeParameter(Type type) - { - return declaringType.GetGenericTypeArgument(type.GenericParameterPosition); - } - - public Type BindMethodParameter(Type type) - { - if (methodArgs == null) - { - return type; - } - return methodArgs[type.GenericParameterPosition]; - } - } - - internal MethodSignature Bind(Type type, Type[] methodArgs) - { - Binder binder = new Binder(type, methodArgs); - return new MethodSignature(returnType.BindTypeParameters(binder), - BindTypeParameters(binder, parameterTypes), - modifiers.Bind(binder), - callingConvention, genericParamCount); - } - - private sealed class Unbinder : IGenericBinder - { - internal static readonly Unbinder Instance = new Unbinder(); - - private Unbinder() - { - } - - public Type BindTypeParameter(Type type) - { - return type; - } - - public Type BindMethodParameter(Type type) - { - return UnboundGenericMethodParameter.Make(type.GenericParameterPosition); - } - } - - internal static MethodSignature MakeFromBuilder(Type returnType, Type[] parameterTypes, PackedCustomModifiers modifiers, CallingConventions callingConvention, int genericParamCount) - { - if (genericParamCount > 0) - { - returnType = returnType.BindTypeParameters(Unbinder.Instance); - parameterTypes = BindTypeParameters(Unbinder.Instance, parameterTypes); - modifiers = modifiers.Bind(Unbinder.Instance); - } - return new MethodSignature(returnType, parameterTypes, modifiers, callingConvention, genericParamCount); - } - - internal bool MatchParameterTypes(MethodSignature other) - { - return Util.ArrayEquals(other.parameterTypes, parameterTypes); - } - - internal bool MatchParameterTypes(Type[] types) - { - return Util.ArrayEquals(types, parameterTypes); - } - - internal override void WriteSig(ModuleBuilder module, ByteBuffer bb) - { - WriteSigImpl(module, bb, parameterTypes.Length); - } - - internal void WriteMethodRefSig(ModuleBuilder module, ByteBuffer bb, Type[] optionalParameterTypes, CustomModifiers[] customModifiers) - { - WriteSigImpl(module, bb, parameterTypes.Length + optionalParameterTypes.Length); - if (optionalParameterTypes.Length > 0) - { - bb.Write(SENTINEL); - for (int i = 0; i < optionalParameterTypes.Length; i++) - { - WriteCustomModifiers(module, bb, Util.NullSafeElementAt(customModifiers, i)); - WriteType(module, bb, optionalParameterTypes[i]); - } - } - } - - private void WriteSigImpl(ModuleBuilder module, ByteBuffer bb, int parameterCount) - { - byte first; - if ((callingConvention & CallingConventions.Any) == CallingConventions.VarArgs) - { - Debug.Assert(genericParamCount == 0); - first = VARARG; - } - else if (genericParamCount > 0) - { - first = GENERIC; - } - else - { - first = DEFAULT; - } - if ((callingConvention & CallingConventions.HasThis) != 0) - { - first |= HASTHIS; - } - if ((callingConvention & CallingConventions.ExplicitThis) != 0) - { - first |= EXPLICITTHIS; - } - bb.Write(first); - if (genericParamCount > 0) - { - bb.WriteCompressedInt(genericParamCount); - } - bb.WriteCompressedInt(parameterCount); - // RetType - WriteCustomModifiers(module, bb, modifiers.GetReturnTypeCustomModifiers()); - WriteType(module, bb, returnType); - // Param - for (int i = 0; i < parameterTypes.Length; i++) - { - WriteCustomModifiers(module, bb, modifiers.GetParameterCustomModifiers(i)); - WriteType(module, bb, parameterTypes[i]); - } - } - } - - struct PackedCustomModifiers - { - // element 0 is the return type, the rest are the parameters - private readonly CustomModifiers[] customModifiers; - - private PackedCustomModifiers(CustomModifiers[] customModifiers) - { - this.customModifiers = customModifiers; - } - - public override int GetHashCode() - { - return Util.GetHashCode(customModifiers); - } - - public override bool Equals(object obj) - { - PackedCustomModifiers? other = obj as PackedCustomModifiers?; - return other != null && Equals(other.Value); - } - - internal bool Equals(PackedCustomModifiers other) - { - return Util.ArrayEquals(customModifiers, other.customModifiers); - } - - internal CustomModifiers GetReturnTypeCustomModifiers() - { - if (customModifiers == null) - { - return new CustomModifiers(); - } - return customModifiers[0]; - } - - internal CustomModifiers GetParameterCustomModifiers(int index) - { - if (customModifiers == null) - { - return new CustomModifiers(); - } - return customModifiers[index + 1]; - } - - internal PackedCustomModifiers Bind(IGenericBinder binder) - { - if (customModifiers == null) - { - return new PackedCustomModifiers(); - } - CustomModifiers[] expanded = new CustomModifiers[customModifiers.Length]; - for (int i = 0; i < customModifiers.Length; i++) - { - expanded[i] = customModifiers[i].Bind(binder); - } - return new PackedCustomModifiers(expanded); - } - - // this method make a copy of the incoming arrays (where necessary) and returns a normalized modifiers array - internal static PackedCustomModifiers CreateFromExternal(Type[] returnOptional, Type[] returnRequired, Type[][] parameterOptional, Type[][] parameterRequired, int parameterCount) - { - CustomModifiers[] modifiers = null; - Pack(ref modifiers, 0, CustomModifiers.FromReqOpt(returnRequired, returnOptional), parameterCount + 1); - for (int i = 0; i < parameterCount; i++) - { - Pack(ref modifiers, i + 1, CustomModifiers.FromReqOpt(Util.NullSafeElementAt(parameterRequired, i), Util.NullSafeElementAt(parameterOptional, i)), parameterCount + 1); - } - return new PackedCustomModifiers(modifiers); - } - - internal static PackedCustomModifiers CreateFromExternal(CustomModifiers returnTypeCustomModifiers, CustomModifiers[] parameterTypeCustomModifiers, int parameterCount) - { - CustomModifiers[] customModifiers = null; - Pack(ref customModifiers, 0, returnTypeCustomModifiers, parameterCount + 1); - if (parameterTypeCustomModifiers != null) - { - for (int i = 0; i < parameterCount; i++) - { - Pack(ref customModifiers, i + 1, parameterTypeCustomModifiers[i], parameterCount + 1); - } - } - return new PackedCustomModifiers(customModifiers); - } - - internal static PackedCustomModifiers Wrap(CustomModifiers[] modifiers) - { - return new PackedCustomModifiers(modifiers); - } - - internal static void Pack(ref CustomModifiers[] array, int index, CustomModifiers mods, int count) - { - if (!mods.IsEmpty) - { - if (array == null) - { - array = new CustomModifiers[count]; - } - array[index] = mods; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Missing.cs b/mcs/class/IKVM.Reflection/Missing.cs deleted file mode 100644 index 6d2364b01b6..00000000000 --- a/mcs/class/IKVM.Reflection/Missing.cs +++ /dev/null @@ -1,1162 +0,0 @@ -/* - Copyright (C) 2011-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace IKVM.Reflection -{ - [Serializable] - public sealed class MissingAssemblyException : InvalidOperationException - { - [NonSerialized] - private readonly MissingAssembly assembly; - - internal MissingAssemblyException(MissingAssembly assembly) - : base("Assembly '" + assembly.FullName + "' is a missing assembly and does not support the requested operation.") - { - this.assembly = assembly; - } - - private MissingAssemblyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - - public Assembly Assembly - { - get { return assembly; } - } - } - - [Serializable] - public sealed class MissingModuleException : InvalidOperationException - { - [NonSerialized] - private readonly MissingModule module; - - internal MissingModuleException(MissingModule module) - : base("Module from missing assembly '" + module.Assembly.FullName + "' does not support the requested operation.") - { - this.module = module; - } - - private MissingModuleException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - - public Module Module - { - get { return module; } - } - } - - [Serializable] - public sealed class MissingMemberException : InvalidOperationException - { - [NonSerialized] - private readonly MemberInfo member; - - internal MissingMemberException(MemberInfo member) - : base("Member '" + member + "' is a missing member and does not support the requested operation.") - { - this.member = member; - } - - private MissingMemberException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - - public MemberInfo MemberInfo - { - get { return member; } - } - } - - public struct MissingGenericMethodBuilder - { - private readonly MissingMethod method; - - public MissingGenericMethodBuilder(Type declaringType, CallingConventions callingConvention, string name, int genericParameterCount) - { - method = new MissingMethod(declaringType, name, new MethodSignature(null, null, new PackedCustomModifiers(), callingConvention, genericParameterCount)); - } - - public Type[] GetGenericArguments() - { - return method.GetGenericArguments(); - } - - public void SetSignature(Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - method.signature = new MethodSignature( - returnType ?? method.Module.universe.System_Void, - Util.Copy(parameterTypes), - PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length), - method.signature.CallingConvention, - method.signature.GenericParameterCount); - } - - [Obsolete("Please use SetSignature(Type, CustomModifiers, Type[], CustomModifiers[]) instead.")] - public void SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - method.signature = new MethodSignature( - returnType ?? method.Module.universe.System_Void, - Util.Copy(parameterTypes), - PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length), - method.signature.CallingConvention, - method.signature.GenericParameterCount); - } - - public MethodInfo Finish() - { - return method; - } - } - - sealed class MissingAssembly : Assembly - { - private readonly MissingModule module; - - internal MissingAssembly(Universe universe, string name) - : base(universe) - { - module = new MissingModule(this); - this.fullName = name; - } - - public override Type[] GetTypes() - { - throw new MissingAssemblyException(this); - } - - public override AssemblyName GetName() - { - return new AssemblyName(fullName); - } - - public override string ImageRuntimeVersion - { - get { throw new MissingAssemblyException(this); } - } - - public override Module ManifestModule - { - get { return module; } - } - - public override MethodInfo EntryPoint - { - get { throw new MissingAssemblyException(this); } - } - - public override string Location - { - get { throw new MissingAssemblyException(this); } - } - - public override AssemblyName[] GetReferencedAssemblies() - { - throw new MissingAssemblyException(this); - } - - public override Module[] GetModules(bool getResourceModules) - { - throw new MissingAssemblyException(this); - } - - public override Module[] GetLoadedModules(bool getResourceModules) - { - throw new MissingAssemblyException(this); - } - - public override Module GetModule(string name) - { - throw new MissingAssemblyException(this); - } - - public override string[] GetManifestResourceNames() - { - throw new MissingAssemblyException(this); - } - - public override ManifestResourceInfo GetManifestResourceInfo(string resourceName) - { - throw new MissingAssemblyException(this); - } - - public override System.IO.Stream GetManifestResourceStream(string resourceName) - { - throw new MissingAssemblyException(this); - } - - public override bool __IsMissing - { - get { return true; } - } - - internal override Type FindType(TypeName typeName) - { - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - return null; - } - - internal override IList GetCustomAttributesData(Type attributeType) - { - throw new MissingAssemblyException(this); - } - } - - sealed class MissingModule : NonPEModule - { - private readonly MissingAssembly assembly; - - internal MissingModule(MissingAssembly assembly) - : base(assembly.universe) - { - this.assembly = assembly; - } - - public override int MDStreamVersion - { - get { throw new MissingModuleException(this); } - } - - public override Assembly Assembly - { - get { return assembly; } - } - - public override string FullyQualifiedName - { - get { throw new MissingModuleException(this); } - } - - public override string Name - { - get { throw new MissingModuleException(this); } - } - - public override Guid ModuleVersionId - { - get { throw new MissingModuleException(this); } - } - - public override string ScopeName - { - get { throw new MissingModuleException(this); } - } - - internal override Type FindType(TypeName typeName) - { - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - return null; - } - - internal override void GetTypesImpl(System.Collections.Generic.List list) - { - throw new MissingModuleException(this); - } - - public override void __GetDataDirectoryEntry(int index, out int rva, out int length) - { - throw new MissingModuleException(this); - } - - public override IList __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security) - { - throw new MissingModuleException(this); - } - - public override long __RelativeVirtualAddressToFileOffset(int rva) - { - throw new MissingModuleException(this); - } - - public override __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw new MissingModuleException(this); - } - - public override int __Subsystem - { - get { throw new MissingModuleException(this); } - } - - internal override void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule) - { - throw new MissingModuleException(this); - } - - public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) - { - throw new MissingModuleException(this); - } - - public override bool __IsMissing - { - get { return true; } - } - - protected override Exception InvalidOperationException() - { - return new MissingModuleException(this); - } - - protected override Exception NotSupportedException() - { - return new MissingModuleException(this); - } - - protected override Exception ArgumentOutOfRangeException() - { - return new MissingModuleException(this); - } - } - - sealed class MissingType : Type - { - private readonly Module module; - private readonly Type declaringType; - private readonly string ns; - private readonly string name; - private Type[] typeArgs; - private int token; - - internal MissingType(Module module, Type declaringType, string ns, string name) - { - this.module = module; - this.declaringType = declaringType; - this.ns = ns; - this.name = name; - MarkEnumOrValueType(ns, name); - } - - internal override MethodBase FindMethod(string name, MethodSignature signature) - { - MethodInfo method = new MissingMethod(this, name, signature); - if (name == ".ctor") - { - return new ConstructorInfoImpl(method); - } - return method; - } - - internal override FieldInfo FindField(string name, FieldSignature signature) - { - return new MissingField(this, name, signature); - } - - internal override Type FindNestedType(TypeName name) - { - return null; - } - - internal override Type FindNestedTypeIgnoreCase(TypeName lowerCaseName) - { - return null; - } - - public override bool __IsMissing - { - get { return true; } - } - - public override Type DeclaringType - { - get { return declaringType; } - } - - public override string __Name - { - get { return name; } - } - - public override string __Namespace - { - get { return ns; } - } - - public override string Name - { - get { return TypeNameParser.Escape(name); } - } - - public override string FullName - { - get { return GetFullName(); } - } - - public override Module Module - { - get { return module; } - } - - public override int MetadataToken - { - get { return token; } - } - - public override bool IsValueType - { - get - { - switch (typeFlags & (TypeFlags.ValueType | TypeFlags.NotValueType)) - { - case TypeFlags.ValueType: - return true; - case TypeFlags.NotValueType: - return false; - default: - if (module.universe.ResolveMissingTypeIsValueType(this)) - { - typeFlags |= TypeFlags.ValueType; - } - else - { - typeFlags |= TypeFlags.NotValueType; - } - return (typeFlags & TypeFlags.ValueType) != 0; - } - } - } - - public override Type BaseType - { - get { throw new MissingMemberException(this); } - } - - public override TypeAttributes Attributes - { - get { throw new MissingMemberException(this); } - } - - public override Type[] __GetDeclaredTypes() - { - throw new MissingMemberException(this); - } - - public override Type[] __GetDeclaredInterfaces() - { - throw new MissingMemberException(this); - } - - public override MethodBase[] __GetDeclaredMethods() - { - throw new MissingMemberException(this); - } - - public override __MethodImplMap __GetMethodImplMap() - { - throw new MissingMemberException(this); - } - - public override FieldInfo[] __GetDeclaredFields() - { - throw new MissingMemberException(this); - } - - public override EventInfo[] __GetDeclaredEvents() - { - throw new MissingMemberException(this); - } - - public override PropertyInfo[] __GetDeclaredProperties() - { - throw new MissingMemberException(this); - } - - public override CustomModifiers __GetCustomModifiers() - { - throw new MissingMemberException(this); - } - - public override Type[] GetGenericArguments() - { - throw new MissingMemberException(this); - } - - public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - throw new MissingMemberException(this); - } - - public override StructLayoutAttribute StructLayoutAttribute - { - get { throw new MissingMemberException(this); } - } - - public override bool IsGenericType - { - get { throw new MissingMemberException(this); } - } - - public override bool IsGenericTypeDefinition - { - get { throw new MissingMemberException(this); } - } - - internal override Type GetGenericTypeArgument(int index) - { - if (typeArgs == null) - { - typeArgs = new Type[index + 1]; - } - else if (typeArgs.Length <= index) - { - Array.Resize(ref typeArgs, index + 1); - } - return typeArgs[index] ?? (typeArgs[index] = new MissingTypeParameter(this, index)); - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - return this; - } - - internal override Type SetMetadataTokenForMissing(int token) - { - this.token = token; - return this; - } - - internal override bool IsBaked - { - get { throw new MissingMemberException(this); } - } - } - - sealed class MissingTypeParameter : IKVM.Reflection.Reader.TypeParameterType - { - private readonly MemberInfo owner; - private readonly int index; - - internal MissingTypeParameter(MemberInfo owner, int index) - { - this.owner = owner; - this.index = index; - } - - public override Module Module - { - get { return owner.Module; } - } - - public override string Name - { - get { return null; } - } - - public override int GenericParameterPosition - { - get { return index; } - } - - public override MethodBase DeclaringMethod - { - get { return owner as MethodBase; } - } - - public override Type DeclaringType - { - get { return owner as Type; } - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - if (owner is MethodBase) - { - return binder.BindMethodParameter(this); - } - else - { - return binder.BindTypeParameter(this); - } - } - - internal override bool IsBaked - { - get { return owner.IsBaked; } - } - } - - sealed class MissingMethod : MethodInfo - { - private readonly Type declaringType; - private readonly string name; - internal MethodSignature signature; - private MethodInfo forwarder; - private Type[] typeArgs; - - internal MissingMethod(Type declaringType, string name, MethodSignature signature) - { - this.declaringType = declaringType; - this.name = name; - this.signature = signature; - } - - private MethodInfo Forwarder - { - get - { - MethodInfo method = TryGetForwarder(); - if (method == null) - { - throw new MissingMemberException(this); - } - return method; - } - } - - private MethodInfo TryGetForwarder() - { - if (forwarder == null && !declaringType.__IsMissing) - { - MethodBase mb = declaringType.FindMethod(name, signature); - ConstructorInfo ci = mb as ConstructorInfo; - if (ci != null) - { - forwarder = ci.GetMethodInfo(); - } - else - { - forwarder = (MethodInfo)mb; - } - } - return forwarder; - } - - public override bool __IsMissing - { - get { return TryGetForwarder() == null; } - } - - public override Type ReturnType - { - get { return signature.GetReturnType(this); } - } - - public override ParameterInfo ReturnParameter - { - get { return new ParameterInfoImpl(this, -1); } - } - - internal override MethodSignature MethodSignature - { - get { return signature; } - } - - internal override int ParameterCount - { - get { return signature.GetParameterCount(); } - } - - private sealed class ParameterInfoImpl : ParameterInfo - { - private readonly MissingMethod method; - private readonly int index; - - internal ParameterInfoImpl(MissingMethod method, int index) - { - this.method = method; - this.index = index; - } - - private ParameterInfo Forwarder - { - get { return index == -1 ? method.Forwarder.ReturnParameter : method.Forwarder.GetParameters()[index]; } - } - - public override string Name - { - get { return Forwarder.Name; } - } - - public override Type ParameterType - { - get { return index == -1 ? method.signature.GetReturnType(method) : method.signature.GetParameterType(method, index); } - } - - public override ParameterAttributes Attributes - { - get { return Forwarder.Attributes; } - } - - public override int Position - { - get { return index; } - } - - public override object RawDefaultValue - { - get { return Forwarder.RawDefaultValue; } - } - - public override CustomModifiers __GetCustomModifiers() - { - return index == -1 - ? method.signature.GetReturnTypeCustomModifiers(method) - : method.signature.GetParameterCustomModifiers(method, index); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - return Forwarder.__TryGetFieldMarshal(out fieldMarshal); - } - - public override MemberInfo Member - { - get { return method; } - } - - public override int MetadataToken - { - get { return Forwarder.MetadataToken; } - } - - internal override Module Module - { - get { return method.Module; } - } - - public override string ToString() - { - return Forwarder.ToString(); - } - } - - public override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameters = new ParameterInfo[signature.GetParameterCount()]; - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoImpl(this, i); - } - return parameters; - } - - public override MethodAttributes Attributes - { - get { return Forwarder.Attributes; } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return Forwarder.GetMethodImplementationFlags(); - } - - public override MethodBody GetMethodBody() - { - return Forwarder.GetMethodBody(); - } - - public override int __MethodRVA - { - get { return Forwarder.__MethodRVA; } - } - - public override CallingConventions CallingConvention - { - get { return signature.CallingConvention; } - } - - internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module) - { - MethodInfo method = TryGetForwarder(); - if (method != null) - { - return method.ImportTo(module); - } - return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature); - } - - public override string Name - { - get { return name; } - } - - public override Type DeclaringType - { - get { return declaringType.IsModulePseudoType ? null : declaringType; } - } - - public override Module Module - { - get { return declaringType.Module; } - } - - public override bool Equals(object obj) - { - MissingMethod other = obj as MissingMethod; - return other != null - && other.declaringType == declaringType - && other.name == name - && other.signature.Equals(signature); - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() ^ name.GetHashCode() ^ signature.GetHashCode(); - } - - internal override MethodBase BindTypeParameters(Type type) - { - MethodInfo forwarder = TryGetForwarder(); - if (forwarder != null) - { - return forwarder.BindTypeParameters(type); - } - return new GenericMethodInstance(type, this, null); - } - - public override bool ContainsGenericParameters - { - get { return Forwarder.ContainsGenericParameters; } - } - - public override Type[] GetGenericArguments() - { - MethodInfo method = TryGetForwarder(); - if (method != null) - { - return Forwarder.GetGenericArguments(); - } - if (typeArgs == null) - { - typeArgs = new Type[signature.GenericParameterCount]; - for (int i = 0; i < typeArgs.Length; i++) - { - typeArgs[i] = new MissingTypeParameter(this, i); - } - } - return Util.Copy(typeArgs); - } - - internal override Type GetGenericMethodArgument(int index) - { - return GetGenericArguments()[index]; - } - - internal override int GetGenericMethodArgumentCount() - { - return Forwarder.GetGenericMethodArgumentCount(); - } - - public override MethodInfo GetGenericMethodDefinition() - { - return Forwarder.GetGenericMethodDefinition(); - } - - internal override MethodInfo GetMethodOnTypeDefinition() - { - return Forwarder.GetMethodOnTypeDefinition(); - } - - internal override bool HasThis - { - get { return (signature.CallingConvention & (CallingConventions.HasThis | CallingConventions.ExplicitThis)) == CallingConventions.HasThis; } - } - - public override bool IsGenericMethod - { - get { return IsGenericMethodDefinition; } - } - - public override bool IsGenericMethodDefinition - { - get { return signature.GenericParameterCount != 0; } - } - - public override MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - MethodInfo method = TryGetForwarder(); - if (method != null) - { - return method.MakeGenericMethod(typeArguments); - } - return new GenericMethodInstance(declaringType, this, typeArguments); - } - - public override int MetadataToken - { - get { return Forwarder.MetadataToken; } - } - - internal override int GetCurrentToken() - { - return Forwarder.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return Forwarder.IsBaked; } - } - } - - sealed class MissingField : FieldInfo - { - private readonly Type declaringType; - private readonly string name; - private readonly FieldSignature signature; - private FieldInfo forwarder; - - internal MissingField(Type declaringType, string name, FieldSignature signature) - { - this.declaringType = declaringType; - this.name = name; - this.signature = signature; - } - - private FieldInfo Forwarder - { - get - { - FieldInfo field = TryGetForwarder(); - if (field == null) - { - throw new MissingMemberException(this); - } - return field; - } - } - - private FieldInfo TryGetForwarder() - { - if (forwarder == null && !declaringType.__IsMissing) - { - forwarder = declaringType.FindField(name, signature); - } - return forwarder; - } - - public override bool __IsMissing - { - get { return TryGetForwarder() == null; } - } - - public override FieldAttributes Attributes - { - get { return Forwarder.Attributes; } - } - - public override void __GetDataFromRVA(byte[] data, int offset, int length) - { - Forwarder.__GetDataFromRVA(data, offset, length); - } - - public override int __FieldRVA - { - get { return Forwarder.__FieldRVA; } - } - - public override bool __TryGetFieldOffset(out int offset) - { - return Forwarder.__TryGetFieldOffset(out offset); - } - - public override object GetRawConstantValue() - { - return Forwarder.GetRawConstantValue(); - } - - internal override FieldSignature FieldSignature - { - get { return signature; } - } - - internal override int ImportTo(IKVM.Reflection.Emit.ModuleBuilder module) - { - FieldInfo field = TryGetForwarder(); - if (field != null) - { - return field.ImportTo(module); - } - return module.ImportMethodOrField(declaringType, this.Name, this.FieldSignature); - } - - public override string Name - { - get { return name; } - } - - public override Type DeclaringType - { - get { return declaringType.IsModulePseudoType ? null : declaringType; } - } - - public override Module Module - { - get { return declaringType.Module; } - } - - internal override FieldInfo BindTypeParameters(Type type) - { - FieldInfo forwarder = TryGetForwarder(); - if (forwarder != null) - { - return forwarder.BindTypeParameters(type); - } - return new GenericFieldInstance(type, this); - } - - public override int MetadataToken - { - get { return Forwarder.MetadataToken; } - } - - public override bool Equals(object obj) - { - MissingField other = obj as MissingField; - return other != null - && other.declaringType == declaringType - && other.name == name - && other.signature.Equals(signature); - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() ^ name.GetHashCode() ^ signature.GetHashCode(); - } - - public override string ToString() - { - return this.FieldType.Name + " " + this.Name; - } - - internal override int GetCurrentToken() - { - return Forwarder.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return Forwarder.IsBaked; } - } - } - - // NOTE this is currently only used by CustomAttributeData (because there is no other way to refer to a property) - sealed class MissingProperty : PropertyInfo - { - private readonly Type declaringType; - private readonly string name; - private readonly PropertySignature signature; - - internal MissingProperty(Type declaringType, string name, PropertySignature signature) - { - this.declaringType = declaringType; - this.name = name; - this.signature = signature; - } - - public override PropertyAttributes Attributes - { - get { throw new MissingMemberException(this); } - } - - public override bool CanRead - { - get { throw new MissingMemberException(this); } - } - - public override bool CanWrite - { - get { throw new MissingMemberException(this); } - } - - public override MethodInfo GetGetMethod(bool nonPublic) - { - throw new MissingMemberException(this); - } - - public override MethodInfo GetSetMethod(bool nonPublic) - { - throw new MissingMemberException(this); - } - - public override MethodInfo[] GetAccessors(bool nonPublic) - { - throw new MissingMemberException(this); - } - - public override object GetRawConstantValue() - { - throw new MissingMemberException(this); - } - - internal override bool IsPublic - { - get { throw new MissingMemberException(this); } - } - - internal override bool IsNonPrivate - { - get { throw new MissingMemberException(this); } - } - - internal override bool IsStatic - { - get { throw new MissingMemberException(this); } - } - - internal override PropertySignature PropertySignature - { - get { return signature; } - } - - public override string Name - { - get { return name; } - } - - public override Type DeclaringType - { - get { return declaringType; } - } - - public override Module Module - { - get { return declaringType.Module; } - } - - internal override bool IsBaked - { - get { return declaringType.IsBaked; } - } - - internal override int GetCurrentToken() - { - throw new MissingMemberException(this); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Module.cs b/mcs/class/IKVM.Reflection/Module.cs deleted file mode 100644 index d734aae2077..00000000000 --- a/mcs/class/IKVM.Reflection/Module.cs +++ /dev/null @@ -1,670 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using IKVM.Reflection.Metadata; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - public sealed class RawModule : IDisposable - { - private readonly ModuleReader module; - private readonly bool isManifestModule; - private bool imported; - - internal RawModule(ModuleReader module) - { - this.module = module; - this.isManifestModule = module.Assembly != null; - } - - public string Location - { - get { return module.FullyQualifiedName; } - } - - public bool IsManifestModule - { - get { return isManifestModule; } - } - - public Guid ModuleVersionId - { - get { return module.ModuleVersionId; } - } - - private void CheckManifestModule() - { - if (!IsManifestModule) - { - throw new BadImageFormatException("Module does not contain a manifest"); - } - } - - public AssemblyName GetAssemblyName() - { - CheckManifestModule(); - return module.Assembly.GetName(); - } - - public AssemblyName[] GetReferencedAssemblies() - { - return module.__GetReferencedAssemblies(); - } - - public void Dispose() - { - if (!imported) - { - module.stream.Dispose(); - } - } - - internal AssemblyReader ToAssembly() - { - if (imported) - { - throw new InvalidOperationException(); - } - imported = true; - return (AssemblyReader)module.Assembly; - } - - internal Module ToModule(Assembly assembly) - { - if (module.Assembly != null) - { - throw new InvalidOperationException(); - } - imported = true; - module.SetAssembly(assembly); - return module; - } - } - - public abstract class Module : ICustomAttributeProvider - { - internal readonly Universe universe; - internal readonly ModuleTable ModuleTable = new ModuleTable(); - internal readonly TypeRefTable TypeRef = new TypeRefTable(); - internal readonly TypeDefTable TypeDef = new TypeDefTable(); - internal readonly FieldPtrTable FieldPtr = new FieldPtrTable(); - internal readonly FieldTable Field = new FieldTable(); - internal readonly MemberRefTable MemberRef = new MemberRefTable(); - internal readonly ConstantTable Constant = new ConstantTable(); - internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable(); - internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable(); - internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable(); - internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable(); - internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable(); - internal readonly ParamPtrTable ParamPtr = new ParamPtrTable(); - internal readonly ParamTable Param = new ParamTable(); - internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable(); - internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable(); - internal readonly EventMapTable EventMap = new EventMapTable(); - internal readonly EventPtrTable EventPtr = new EventPtrTable(); - internal readonly EventTable Event = new EventTable(); - internal readonly PropertyMapTable PropertyMap = new PropertyMapTable(); - internal readonly PropertyPtrTable PropertyPtr = new PropertyPtrTable(); - internal readonly PropertyTable Property = new PropertyTable(); - internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable(); - internal readonly MethodImplTable MethodImpl = new MethodImplTable(); - internal readonly ModuleRefTable ModuleRef = new ModuleRefTable(); - internal readonly TypeSpecTable TypeSpec = new TypeSpecTable(); - internal readonly ImplMapTable ImplMap = new ImplMapTable(); - internal readonly FieldRVATable FieldRVA = new FieldRVATable(); - internal readonly AssemblyTable AssemblyTable = new AssemblyTable(); - internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable(); - internal readonly MethodPtrTable MethodPtr = new MethodPtrTable(); - internal readonly MethodDefTable MethodDef = new MethodDefTable(); - internal readonly NestedClassTable NestedClass = new NestedClassTable(); - internal readonly FileTable File = new FileTable(); - internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable(); - internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable(); - internal readonly GenericParamTable GenericParam = new GenericParamTable(); - internal readonly MethodSpecTable MethodSpec = new MethodSpecTable(); - internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable(); - - protected Module(Universe universe) - { - this.universe = universe; - } - - internal Table[] GetTables() - { - Table[] tables = new Table[64]; - tables[ModuleTable.Index] = ModuleTable; - tables[TypeRefTable.Index] = TypeRef; - tables[TypeDefTable.Index] = TypeDef; - tables[FieldPtrTable.Index] = FieldPtr; - tables[FieldTable.Index] = Field; - tables[MemberRefTable.Index] = MemberRef; - tables[ConstantTable.Index] = Constant; - tables[CustomAttributeTable.Index] = CustomAttribute; - tables[FieldMarshalTable.Index] = FieldMarshal; - tables[DeclSecurityTable.Index] = DeclSecurity; - tables[ClassLayoutTable.Index] = ClassLayout; - tables[FieldLayoutTable.Index] = FieldLayout; - tables[ParamPtrTable.Index] = ParamPtr; - tables[ParamTable.Index] = Param; - tables[InterfaceImplTable.Index] = InterfaceImpl; - tables[StandAloneSigTable.Index] = StandAloneSig; - tables[EventMapTable.Index] = EventMap; - tables[EventPtrTable.Index] = EventPtr; - tables[EventTable.Index] = Event; - tables[PropertyMapTable.Index] = PropertyMap; - tables[PropertyPtrTable.Index] = PropertyPtr; - tables[PropertyTable.Index] = Property; - tables[MethodSemanticsTable.Index] = MethodSemantics; - tables[MethodImplTable.Index] = MethodImpl; - tables[ModuleRefTable.Index] = ModuleRef; - tables[TypeSpecTable.Index] = TypeSpec; - tables[ImplMapTable.Index] = ImplMap; - tables[FieldRVATable.Index] = FieldRVA; - tables[AssemblyTable.Index] = AssemblyTable; - tables[AssemblyRefTable.Index] = AssemblyRef; - tables[MethodPtrTable.Index] = MethodPtr; - tables[MethodDefTable.Index] = MethodDef; - tables[NestedClassTable.Index] = NestedClass; - tables[FileTable.Index] = File; - tables[ExportedTypeTable.Index] = ExportedType; - tables[ManifestResourceTable.Index] = ManifestResource; - tables[GenericParamTable.Index] = GenericParam; - tables[MethodSpecTable.Index] = MethodSpec; - tables[GenericParamConstraintTable.Index] = GenericParamConstraint; - return tables; - } - - public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length) - { - throw new NotSupportedException(); - } - - public virtual long __RelativeVirtualAddressToFileOffset(int rva) - { - throw new NotSupportedException(); - } - - public virtual bool __GetSectionInfo(int rva, out string name, out int characteristics) - { - throw new NotSupportedException(); - } - - public virtual int __ReadDataFromRVA(int rva, byte[] data, int offset, int length) - { - throw new NotSupportedException(); - } - - public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) - { - throw new NotSupportedException(); - } - - public virtual int __Subsystem - { - get { throw new NotSupportedException(); } - } - - public FieldInfo GetField(string name) - { - return GetField(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); - } - - public FieldInfo GetField(string name, BindingFlags bindingFlags) - { - return IsResource() ? null : GetModuleType().GetField(name, bindingFlags | BindingFlags.DeclaredOnly); - } - - public FieldInfo[] GetFields() - { - return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); - } - - public FieldInfo[] GetFields(BindingFlags bindingFlags) - { - return IsResource() ? Empty.Array : GetModuleType().GetFields(bindingFlags | BindingFlags.DeclaredOnly); - } - - public MethodInfo GetMethod(string name) - { - return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); - } - - public MethodInfo GetMethod(string name, Type[] types) - { - return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, types, null); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers) - { - return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr | BindingFlags.DeclaredOnly, binder, callConv, types, modifiers); - } - - public MethodInfo[] GetMethods() - { - return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly); - } - - public MethodInfo[] GetMethods(BindingFlags bindingFlags) - { - return IsResource() ? Empty.Array : GetModuleType().GetMethods(bindingFlags | BindingFlags.DeclaredOnly); - } - - public ConstructorInfo __ModuleInitializer - { - get { return IsResource() ? null : GetModuleType().TypeInitializer; } - } - - public virtual byte[] ResolveSignature(int metadataToken) - { - throw new NotSupportedException(); - } - - public virtual __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw new NotSupportedException(); - } - - public int MetadataToken - { - get { return IsResource() ? 0 : 1; } - } - - public abstract int MDStreamVersion { get ;} - public abstract Assembly Assembly { get; } - public abstract string FullyQualifiedName { get; } - public abstract string Name { get; } - public abstract Guid ModuleVersionId { get; } - public abstract MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments); - public abstract FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments); - public abstract MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments); - - public abstract string ResolveString(int metadataToken); - public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers); - public abstract string ScopeName { get; } - - internal abstract void GetTypesImpl(List list); - - internal abstract Type FindType(TypeName name); - internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName); - - [Obsolete("Please use __ResolveOptionalParameterTypes(int, Type[], Type[], out CustomModifiers[]) instead.")] - public Type[] __ResolveOptionalParameterTypes(int metadataToken) - { - CustomModifiers[] dummy; - return __ResolveOptionalParameterTypes(metadataToken, null, null, out dummy); - } - - public Type GetType(string className) - { - return GetType(className, false, false); - } - - public Type GetType(string className, bool ignoreCase) - { - return GetType(className, false, ignoreCase); - } - - public Type GetType(string className, bool throwOnError, bool ignoreCase) - { - TypeNameParser parser = TypeNameParser.Parse(className, throwOnError); - if (parser.Error) - { - return null; - } - if (parser.AssemblyName != null) - { - if (throwOnError) - { - throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly."); - } - else - { - return null; - } - } - TypeName typeName = TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart)); - Type type = ignoreCase - ? FindTypeIgnoreCase(typeName.ToLowerInvariant()) - : FindType(typeName); - if (type == null && __IsMissing) - { - throw new MissingModuleException((MissingModule)this); - } - return parser.Expand(type, this.Assembly, throwOnError, className, false, ignoreCase); - } - - public Type[] GetTypes() - { - List list = new List(); - GetTypesImpl(list); - return list.ToArray(); - } - - public Type[] FindTypes(TypeFilter filter, object filterCriteria) - { - List list = new List(); - foreach (Type type in GetTypes()) - { - if (filter(type, filterCriteria)) - { - list.Add(type); - } - } - return list.ToArray(); - } - - public virtual bool IsResource() - { - return false; - } - - public Type ResolveType(int metadataToken) - { - return ResolveType(metadataToken, null, null); - } - - internal sealed class GenericContext : IGenericContext - { - private readonly Type[] genericTypeArguments; - private readonly Type[] genericMethodArguments; - - internal GenericContext(Type[] genericTypeArguments, Type[] genericMethodArguments) - { - this.genericTypeArguments = genericTypeArguments; - this.genericMethodArguments = genericMethodArguments; - } - - public Type GetGenericTypeArgument(int index) - { - return genericTypeArguments[index]; - } - - public Type GetGenericMethodArgument(int index) - { - return genericMethodArguments[index]; - } - } - - public Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - if ((metadataToken >> 24) == TypeSpecTable.Index) - { - return ResolveType(metadataToken, new GenericContext(genericTypeArguments, genericMethodArguments)); - } - else - { - return ResolveType(metadataToken, null); - } - } - - internal abstract Type ResolveType(int metadataToken, IGenericContext context); - - public MethodBase ResolveMethod(int metadataToken) - { - return ResolveMethod(metadataToken, null, null); - } - - public FieldInfo ResolveField(int metadataToken) - { - return ResolveField(metadataToken, null, null); - } - - public MemberInfo ResolveMember(int metadataToken) - { - return ResolveMember(metadataToken, null, null); - } - - public bool IsDefined(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0; - } - - public IList __GetCustomAttributes(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit); - } - - public virtual IList __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security) - { - return Empty.Array; - } - - public abstract AssemblyName[] __GetReferencedAssemblies(); - - public virtual void __ResolveReferencedAssemblies(Assembly[] assemblies) - { - throw new NotSupportedException(); - } - - public abstract string[] __GetReferencedModules(); - - public abstract Type[] __GetReferencedTypes(); - - public abstract Type[] __GetExportedTypes(); - - public virtual bool __IsMissing - { - get { return false; } - } - - public long __ImageBase - { - get { return GetImageBaseImpl(); } - } - - protected abstract long GetImageBaseImpl(); - - public long __StackReserve - { - get { return GetStackReserveImpl(); } - } - - protected abstract long GetStackReserveImpl(); - - public int __FileAlignment - { - get { return GetFileAlignmentImpl(); } - } - - protected abstract int GetFileAlignmentImpl(); - - public DllCharacteristics __DllCharacteristics - { - get { return GetDllCharacteristicsImpl(); } - } - - protected abstract DllCharacteristics GetDllCharacteristicsImpl(); - - public virtual byte[] __ModuleHash - { - get { throw new NotSupportedException(); } - } - - public virtual int __EntryPointRVA - { - get { throw new NotSupportedException(); } - } - - public virtual int __EntryPointToken - { - get { throw new NotSupportedException(); } - } - - public virtual string __ImageRuntimeVersion - { - get { throw new NotSupportedException(); } - } - - public IEnumerable __EnumerateCustomAttributeTable() - { - List list = new List(CustomAttribute.RowCount); - for (int i = 0; i < CustomAttribute.RowCount; i++) - { - list.Add(new CustomAttributeData(this, i)); - } - return list; - } - - [Obsolete] - public List __GetCustomAttributesFor(int token) - { - return CustomAttributeData.GetCustomAttributesImpl(new List(), this, token, null); - } - - internal abstract Type GetModuleType(); - - internal abstract ByteReader GetBlob(int blobIndex); - - internal IList GetDeclarativeSecurity(int metadataToken) - { - List list = new List(); - foreach (int i in DeclSecurity.Filter(metadataToken)) - { - CustomAttributeData.ReadDeclarativeSecurity(this, i, list); - } - return list; - } - - internal virtual void Dispose() - { - } - - internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule) - { - } - - internal virtual string GetString(int index) - { - throw new NotSupportedException(); - } - } - - abstract class NonPEModule : Module - { - protected NonPEModule(Universe universe) - : base(universe) - { - } - - protected virtual Exception InvalidOperationException() - { - return new InvalidOperationException(); - } - - protected virtual Exception NotSupportedException() - { - return new NotSupportedException(); - } - - protected virtual Exception ArgumentOutOfRangeException() - { - return new ArgumentOutOfRangeException(); - } - - internal sealed override Type GetModuleType() - { - throw InvalidOperationException(); - } - - internal sealed override ByteReader GetBlob(int blobIndex) - { - throw InvalidOperationException(); - } - - public sealed override AssemblyName[] __GetReferencedAssemblies() - { - throw NotSupportedException(); - } - - public sealed override string[] __GetReferencedModules() - { - throw NotSupportedException(); - } - - public override Type[] __GetReferencedTypes() - { - throw NotSupportedException(); - } - - public override Type[] __GetExportedTypes() - { - throw NotSupportedException(); - } - - protected sealed override long GetImageBaseImpl() - { - throw NotSupportedException(); - } - - protected sealed override long GetStackReserveImpl() - { - throw NotSupportedException(); - } - - protected sealed override int GetFileAlignmentImpl() - { - throw NotSupportedException(); - } - - protected override DllCharacteristics GetDllCharacteristicsImpl() - { - throw NotSupportedException(); - } - - internal sealed override Type ResolveType(int metadataToken, IGenericContext context) - { - throw ArgumentOutOfRangeException(); - } - - public sealed override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw ArgumentOutOfRangeException(); - } - - public sealed override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw ArgumentOutOfRangeException(); - } - - public sealed override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - throw ArgumentOutOfRangeException(); - } - - public sealed override string ResolveString(int metadataToken) - { - throw ArgumentOutOfRangeException(); - } - - public sealed override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers) - { - throw ArgumentOutOfRangeException(); - } - } - - public delegate bool TypeFilter(Type m, object filterCriteria); - public delegate bool MemberFilter(MemberInfo m, object filterCriteria); -} diff --git a/mcs/class/IKVM.Reflection/ParameterInfo.cs b/mcs/class/IKVM.Reflection/ParameterInfo.cs deleted file mode 100644 index fa704ad764b..00000000000 --- a/mcs/class/IKVM.Reflection/ParameterInfo.cs +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System.Collections.Generic; - -namespace IKVM.Reflection -{ - public abstract class ParameterInfo : ICustomAttributeProvider - { - // prevent external subclasses - internal ParameterInfo() - { - } - - public sealed override bool Equals(object obj) - { - ParameterInfo other = obj as ParameterInfo; - return other != null && other.Member == this.Member && other.Position == this.Position; - } - - public sealed override int GetHashCode() - { - return this.Member.GetHashCode() * 1777 + this.Position; - } - - public static bool operator ==(ParameterInfo p1, ParameterInfo p2) - { - return ReferenceEquals(p1, p2) || (!ReferenceEquals(p1, null) && p1.Equals(p2)); - } - - public static bool operator !=(ParameterInfo p1, ParameterInfo p2) - { - return !(p1 == p2); - } - - public abstract string Name { get; } - public abstract Type ParameterType { get; } - public abstract ParameterAttributes Attributes { get; } - public abstract int Position { get; } - public abstract object RawDefaultValue { get; } - public abstract CustomModifiers __GetCustomModifiers(); - public abstract bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal); - public abstract MemberInfo Member { get; } - public abstract int MetadataToken { get; } - internal abstract Module Module { get; } - - public Type[] GetOptionalCustomModifiers() - { - return __GetCustomModifiers().GetOptional(); - } - - public Type[] GetRequiredCustomModifiers() - { - return __GetCustomModifiers().GetRequired(); - } - - public bool IsIn - { - get { return (Attributes & ParameterAttributes.In) != 0; } - } - - public bool IsOut - { - get { return (Attributes & ParameterAttributes.Out) != 0; } - } - - public bool IsLcid - { - get { return (Attributes & ParameterAttributes.Lcid) != 0; } - } - - public bool IsRetval - { - get { return (Attributes & ParameterAttributes.Retval) != 0; } - } - - public bool IsOptional - { - get { return (Attributes & ParameterAttributes.Optional) != 0; } - } - - public bool IsDefined(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0; - } - - public IList __GetCustomAttributes(Type attributeType, bool inherit) - { - return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit); - } - } - - sealed class ParameterInfoWrapper : ParameterInfo - { - private readonly MemberInfo member; - private readonly ParameterInfo forward; - - internal ParameterInfoWrapper(MemberInfo member, ParameterInfo forward) - { - this.member = member; - this.forward = forward; - } - - public override string Name - { - get { return forward.Name; } - } - - public override Type ParameterType - { - get { return forward.ParameterType; } - } - - public override ParameterAttributes Attributes - { - get { return forward.Attributes; } - } - - public override int Position - { - get { return forward.Position; } - } - - public override object RawDefaultValue - { - get { return forward.RawDefaultValue; } - } - - public override CustomModifiers __GetCustomModifiers() - { - return forward.__GetCustomModifiers(); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - return forward.__TryGetFieldMarshal(out fieldMarshal); - } - - public override MemberInfo Member - { - get { return member; } - } - - public override int MetadataToken - { - get { return forward.MetadataToken; } - } - - internal override Module Module - { - get { return member.Module; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/ParameterModifier.cs b/mcs/class/IKVM.Reflection/ParameterModifier.cs deleted file mode 100644 index 605cca48fdc..00000000000 --- a/mcs/class/IKVM.Reflection/ParameterModifier.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection -{ - public struct ParameterModifier - { - private readonly bool[] values; - - public ParameterModifier(int parameterCount) - { - values = new bool[parameterCount]; - } - - public bool this[int index] - { - get { return values[index]; } - set { values[index] = value; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Properties/AssemblyInfo.cs b/mcs/class/IKVM.Reflection/Properties/AssemblyInfo.cs deleted file mode 100644 index f453241e602..00000000000 --- a/mcs/class/IKVM.Reflection/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System.Reflection; - -[assembly: AssemblyTitle("IKVM.Reflection")] -[assembly: AssemblyDescription("Alternative implementation of System.Reflection[.Emit]")] diff --git a/mcs/class/IKVM.Reflection/PropertyInfo.cs b/mcs/class/IKVM.Reflection/PropertyInfo.cs deleted file mode 100644 index b05d07fb0c8..00000000000 --- a/mcs/class/IKVM.Reflection/PropertyInfo.cs +++ /dev/null @@ -1,345 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; - -namespace IKVM.Reflection -{ - public abstract class PropertyInfo : MemberInfo - { - // prevent external subclasses - internal PropertyInfo() - { - } - - public sealed override MemberTypes MemberType - { - get { return MemberTypes.Property; } - } - - public abstract PropertyAttributes Attributes { get; } - public abstract bool CanRead { get; } - public abstract bool CanWrite { get; } - public abstract MethodInfo GetGetMethod(bool nonPublic); - public abstract MethodInfo GetSetMethod(bool nonPublic); - public abstract MethodInfo[] GetAccessors(bool nonPublic); - public abstract object GetRawConstantValue(); - internal abstract bool IsPublic { get; } - internal abstract bool IsNonPrivate { get; } - internal abstract bool IsStatic { get; } - internal abstract PropertySignature PropertySignature { get; } - - private sealed class ParameterInfoImpl : ParameterInfo - { - private readonly PropertyInfo property; - private readonly int parameter; - - internal ParameterInfoImpl(PropertyInfo property, int parameter) - { - this.property = property; - this.parameter = parameter; - } - - public override string Name - { - get { return null; } - } - - public override Type ParameterType - { - get { return property.PropertySignature.GetParameter(parameter); } - } - - public override ParameterAttributes Attributes - { - get { return ParameterAttributes.None; } - } - - public override int Position - { - get { return parameter; } - } - - public override object RawDefaultValue - { - get { throw new InvalidOperationException(); } - } - - public override CustomModifiers __GetCustomModifiers() - { - return property.PropertySignature.GetParameterCustomModifiers(parameter); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - fieldMarshal = new FieldMarshal(); - return false; - } - - public override MemberInfo Member - { - get { return property; } - } - - public override int MetadataToken - { - get { return 0x08000000; } - } - - internal override Module Module - { - get { return property.Module; } - } - } - - public virtual ParameterInfo[] GetIndexParameters() - { - ParameterInfo[] parameters = new ParameterInfo[this.PropertySignature.ParameterCount]; - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoImpl(this, i); - } - return parameters; - } - - public Type PropertyType - { - get { return this.PropertySignature.PropertyType; } - } - - public CustomModifiers __GetCustomModifiers() - { - return this.PropertySignature.GetCustomModifiers(); - } - - public Type[] GetRequiredCustomModifiers() - { - return __GetCustomModifiers().GetRequired(); - } - - public Type[] GetOptionalCustomModifiers() - { - return __GetCustomModifiers().GetOptional(); - } - - public bool IsSpecialName - { - get { return (Attributes & PropertyAttributes.SpecialName) != 0; } - } - - public MethodInfo GetGetMethod() - { - return GetGetMethod(false); - } - - public MethodInfo GetSetMethod() - { - return GetSetMethod(false); - } - - public MethodInfo[] GetAccessors() - { - return GetAccessors(false); - } - - public CallingConventions __CallingConvention - { - get { return this.PropertySignature.CallingConvention; } - } - - internal virtual PropertyInfo BindTypeParameters(Type type) - { - return new GenericPropertyInfo(this.DeclaringType.BindTypeParameters(type), this); - } - - public override string ToString() - { - return this.DeclaringType.ToString() + " " + Name; - } - - internal sealed override bool BindingFlagsMatch(BindingFlags flags) - { - return BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static, BindingFlags.Instance); - } - - internal sealed override bool BindingFlagsMatchInherited(BindingFlags flags) - { - return IsNonPrivate - && BindingFlagsMatch(IsPublic, flags, BindingFlags.Public, BindingFlags.NonPublic) - && BindingFlagsMatch(IsStatic, flags, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance); - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - return new PropertyInfoWithReflectedType(type, this); - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - // properties don't have pseudo custom attributes - return null; - } - } - - sealed class PropertyInfoWithReflectedType : PropertyInfo - { - private readonly Type reflectedType; - private readonly PropertyInfo property; - - internal PropertyInfoWithReflectedType(Type reflectedType, PropertyInfo property) - { - this.reflectedType = reflectedType; - this.property = property; - } - - public override PropertyAttributes Attributes - { - get { return property.Attributes; } - } - - public override bool CanRead - { - get { return property.CanRead; } - } - - public override bool CanWrite - { - get { return property.CanWrite; } - } - - public override MethodInfo GetGetMethod(bool nonPublic) - { - return SetReflectedType(property.GetGetMethod(nonPublic), reflectedType); - } - - public override MethodInfo GetSetMethod(bool nonPublic) - { - return SetReflectedType(property.GetSetMethod(nonPublic), reflectedType); - } - - public override MethodInfo[] GetAccessors(bool nonPublic) - { - return SetReflectedType(property.GetAccessors(nonPublic), reflectedType); - } - - public override object GetRawConstantValue() - { - return property.GetRawConstantValue(); - } - - internal override bool IsPublic - { - get { return property.IsPublic; } - } - - internal override bool IsNonPrivate - { - get { return property.IsNonPrivate; } - } - - internal override bool IsStatic - { - get { return property.IsStatic; } - } - - internal override PropertySignature PropertySignature - { - get { return property.PropertySignature; } - } - - public override ParameterInfo[] GetIndexParameters() - { - ParameterInfo[] parameters = property.GetIndexParameters(); - for (int i = 0; i < parameters.Length; i++) - { - parameters[i] = new ParameterInfoWrapper(this, parameters[i]); - } - return parameters; - } - - internal override PropertyInfo BindTypeParameters(Type type) - { - return property.BindTypeParameters(type); - } - - public override string ToString() - { - return property.ToString(); - } - - public override bool __IsMissing - { - get { return property.__IsMissing; } - } - - public override Type DeclaringType - { - get { return property.DeclaringType; } - } - - public override Type ReflectedType - { - get { return reflectedType; } - } - - public override bool Equals(object obj) - { - PropertyInfoWithReflectedType other = obj as PropertyInfoWithReflectedType; - return other != null - && other.reflectedType == reflectedType - && other.property == property; - } - - public override int GetHashCode() - { - return reflectedType.GetHashCode() ^ property.GetHashCode(); - } - - public override int MetadataToken - { - get { return property.MetadataToken; } - } - - public override Module Module - { - get { return property.Module; } - } - - public override string Name - { - get { return property.Name; } - } - - internal override bool IsBaked - { - get { return property.IsBaked; } - } - - internal override int GetCurrentToken() - { - return property.GetCurrentToken(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/PropertySignature.cs b/mcs/class/IKVM.Reflection/PropertySignature.cs deleted file mode 100644 index 9a4a5534d12..00000000000 --- a/mcs/class/IKVM.Reflection/PropertySignature.cs +++ /dev/null @@ -1,186 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - sealed class PropertySignature : Signature - { - private CallingConventions callingConvention; - private readonly Type propertyType; - private readonly Type[] parameterTypes; - private readonly PackedCustomModifiers customModifiers; - - internal static PropertySignature Create(CallingConventions callingConvention, Type propertyType, Type[] parameterTypes, PackedCustomModifiers customModifiers) - { - return new PropertySignature(callingConvention, propertyType, Util.Copy(parameterTypes), customModifiers); - } - - private PropertySignature(CallingConventions callingConvention, Type propertyType, Type[] parameterTypes, PackedCustomModifiers customModifiers) - { - this.callingConvention = callingConvention; - this.propertyType = propertyType; - this.parameterTypes = parameterTypes; - this.customModifiers = customModifiers; - } - - public override bool Equals(object obj) - { - PropertySignature other = obj as PropertySignature; - return other != null - && other.propertyType.Equals(propertyType) - && other.customModifiers.Equals(customModifiers); - } - - public override int GetHashCode() - { - return propertyType.GetHashCode() ^ customModifiers.GetHashCode(); - } - - internal int ParameterCount - { - get { return parameterTypes.Length; } - } - - internal bool HasThis - { - set - { - if (value) - { - callingConvention |= CallingConventions.HasThis; - } - else - { - callingConvention &= ~CallingConventions.HasThis; - } - } - } - - internal Type PropertyType - { - get { return propertyType; } - } - - internal CustomModifiers GetCustomModifiers() - { - return customModifiers.GetReturnTypeCustomModifiers(); - } - - internal PropertySignature ExpandTypeParameters(Type declaringType) - { - return new PropertySignature( - callingConvention, - propertyType.BindTypeParameters(declaringType), - BindTypeParameters(declaringType, parameterTypes), - customModifiers.Bind(declaringType)); - } - - internal override void WriteSig(ModuleBuilder module, ByteBuffer bb) - { - byte flags = PROPERTY; - if ((callingConvention & CallingConventions.HasThis) != 0) - { - flags |= HASTHIS; - } - if ((callingConvention & CallingConventions.ExplicitThis) != 0) - { - flags |= EXPLICITTHIS; - } - if ((callingConvention & CallingConventions.VarArgs) != 0) - { - flags |= VARARG; - } - bb.Write(flags); - bb.WriteCompressedInt(parameterTypes == null ? 0 : parameterTypes.Length); - WriteCustomModifiers(module, bb, customModifiers.GetReturnTypeCustomModifiers()); - WriteType(module, bb, propertyType); - if (parameterTypes != null) - { - for (int i = 0; i < parameterTypes.Length; i++) - { - WriteCustomModifiers(module, bb, customModifiers.GetParameterCustomModifiers(i)); - WriteType(module, bb, parameterTypes[i]); - } - } - } - - internal Type GetParameter(int parameter) - { - return parameterTypes[parameter]; - } - - internal CustomModifiers GetParameterCustomModifiers(int parameter) - { - return customModifiers.GetParameterCustomModifiers(parameter); - } - - internal CallingConventions CallingConvention - { - get { return callingConvention; } - } - - internal bool MatchParameterTypes(Type[] types) - { - return Util.ArrayEquals(types, parameterTypes); - } - - internal static PropertySignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context) - { - byte flags = br.ReadByte(); - if ((flags & PROPERTY) == 0) - { - throw new BadImageFormatException(); - } - CallingConventions callingConvention = CallingConventions.Standard; - if ((flags & HASTHIS) != 0) - { - callingConvention |= CallingConventions.HasThis; - } - if ((flags & EXPLICITTHIS) != 0) - { - callingConvention |= CallingConventions.ExplicitThis; - } - Type returnType; - Type[] parameterTypes; - int paramCount = br.ReadCompressedInt(); - CustomModifiers[] mods = null; - PackedCustomModifiers.Pack(ref mods, 0, CustomModifiers.Read(module, br, context), paramCount + 1); - returnType = ReadRetType(module, br, context); - parameterTypes = new Type[paramCount]; - for (int i = 0; i < parameterTypes.Length; i++) - { - PackedCustomModifiers.Pack(ref mods, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1); - parameterTypes[i] = ReadParam(module, br, context); - } - return new PropertySignature(callingConvention, returnType, parameterTypes, PackedCustomModifiers.Wrap(mods)); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/AssemblyReader.cs b/mcs/class/IKVM.Reflection/Reader/AssemblyReader.cs deleted file mode 100644 index 0004862ee09..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/AssemblyReader.cs +++ /dev/null @@ -1,277 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Configuration.Assemblies; -using System.IO; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class AssemblyReader : Assembly - { - private const int ContainsNoMetaData = 0x0001; - private readonly string location; - private readonly ModuleReader manifestModule; - private readonly Module[] externalModules; - - internal AssemblyReader(string location, ModuleReader manifestModule) - : base(manifestModule.universe) - { - this.location = location; - this.manifestModule = manifestModule; - externalModules = new Module[manifestModule.File.records.Length]; - } - - public override string Location - { - get { return location; } - } - - public override AssemblyName GetName() - { - return GetNameImpl(ref manifestModule.AssemblyTable.records[0]); - } - - private AssemblyName GetNameImpl(ref AssemblyTable.Record rec) - { - AssemblyName name = new AssemblyName(); - name.Name = manifestModule.GetString(rec.Name); - name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber); - if (rec.PublicKey != 0) - { - name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey)); - } - else - { - name.SetPublicKey(Empty.Array); - } - if (rec.Culture != 0) - { - name.Culture = manifestModule.GetString(rec.Culture); - } - else - { - name.Culture = ""; - } - name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId; - name.CodeBase = this.CodeBase; - name.RawFlags = (AssemblyNameFlags)rec.Flags; - return name; - } - - public override Type[] GetTypes() - { - if (externalModules.Length == 0) - { - return manifestModule.GetTypes(); - } - - List list = new List(); - foreach (Module module in GetModules(false)) - { - list.AddRange(module.GetTypes()); - } - return list.ToArray(); - } - - internal override Type FindType(TypeName typeName) - { - Type type = manifestModule.FindType(typeName); - for (int i = 0; type == null && i < externalModules.Length; i++) - { - if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0) - { - type = GetModule(i).FindType(typeName); - } - } - return type; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - Type type = manifestModule.FindTypeIgnoreCase(lowerCaseName); - for (int i = 0; type == null && i < externalModules.Length; i++) - { - if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0) - { - type = GetModule(i).FindTypeIgnoreCase(lowerCaseName); - } - } - return type; - } - - public override string ImageRuntimeVersion - { - get { return manifestModule.__ImageRuntimeVersion; } - } - - public override Module ManifestModule - { - get { return manifestModule; } - } - - public override Module[] GetLoadedModules(bool getResourceModules) - { - List list = new List(); - list.Add(manifestModule); - foreach (Module m in externalModules) - { - if (m != null) - { - list.Add(m); - } - } - return list.ToArray(); - } - - public override Module[] GetModules(bool getResourceModules) - { - if (externalModules.Length == 0) - { - return new Module[] { manifestModule }; - } - else - { - List list = new List(); - list.Add(manifestModule); - for (int i = 0; i < manifestModule.File.records.Length; i++) - { - if (getResourceModules || (manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0) - { - list.Add(GetModule(i)); - } - } - return list.ToArray(); - } - } - - public override Module GetModule(string name) - { - if (name.Equals(manifestModule.ScopeName, StringComparison.InvariantCultureIgnoreCase)) - { - return manifestModule; - } - int index = GetModuleIndex(name); - if (index != -1) - { - return GetModule(index); - } - return null; - } - - private int GetModuleIndex(string name) - { - for (int i = 0; i < manifestModule.File.records.Length; i++) - { - if (name.Equals(manifestModule.GetString(manifestModule.File.records[i].Name), StringComparison.InvariantCultureIgnoreCase)) - { - return i; - } - } - return -1; - } - - private Module GetModule(int index) - { - if (externalModules[index] != null) - { - return externalModules[index]; - } - // TODO add ModuleResolve event - string location = Path.Combine(Path.GetDirectoryName(this.location), manifestModule.GetString(manifestModule.File.records[index].Name)); - return LoadModule(index, null, location); - } - - private Module LoadModule(int index, byte[] rawModule, string location) - { - if ((manifestModule.File.records[index].Flags & ContainsNoMetaData) != 0) - { - return externalModules[index] = new ResourceModule(manifestModule, index, location); - } - else - { - if (rawModule == null) - { - rawModule = File.ReadAllBytes(location); - } - return externalModules[index] = new ModuleReader(this, manifestModule.universe, new MemoryStream(rawModule), location); - } - } - - public override Module LoadModule(string moduleName, byte[] rawModule) - { - int index = GetModuleIndex(moduleName); - if (index == -1) - { - throw new ArgumentException(); - } - if (externalModules[index] != null) - { - return externalModules[index]; - } - return LoadModule(index, rawModule, null); - } - - public override MethodInfo EntryPoint - { - get { return manifestModule.GetEntryPoint(); } - } - - public override string[] GetManifestResourceNames() - { - return manifestModule.GetManifestResourceNames(); - } - - public override ManifestResourceInfo GetManifestResourceInfo(string resourceName) - { - return manifestModule.GetManifestResourceInfo(resourceName); - } - - public override Stream GetManifestResourceStream(string resourceName) - { - return manifestModule.GetManifestResourceStream(resourceName); - } - - public override AssemblyName[] GetReferencedAssemblies() - { - return manifestModule.__GetReferencedAssemblies(); - } - - public override AssemblyNameFlags __AssemblyFlags - { - get { return (AssemblyNameFlags)manifestModule.AssemblyTable.records[0].Flags; } - } - - internal string Name - { - get { return manifestModule.GetString(manifestModule.AssemblyTable.records[0].Name); } - } - - internal override IList GetCustomAttributesData(Type attributeType) - { - return CustomAttributeData.GetCustomAttributesImpl(null, manifestModule, 0x20000001, attributeType) ?? CustomAttributeData.EmptyList; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/ByteReader.cs b/mcs/class/IKVM.Reflection/Reader/ByteReader.cs deleted file mode 100644 index a82744fd9d1..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/ByteReader.cs +++ /dev/null @@ -1,194 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; - -namespace IKVM.Reflection.Reader -{ - sealed class ByteReader - { - private byte[] buffer; - private int pos; - private int end; - - internal ByteReader(byte[] buffer, int offset, int length) - { - this.buffer = buffer; - this.pos = offset; - this.end = pos + length; - } - - internal static ByteReader FromBlob(byte[] blobHeap, int blob) - { - ByteReader br = new ByteReader(blobHeap, blob, 4); - int length = br.ReadCompressedInt(); - br.end = br.pos + length; - return br; - } - - internal int Length - { - get { return end - pos; } - } - - internal byte PeekByte() - { - if (pos == end) - throw new BadImageFormatException(); - return buffer[pos]; - } - - internal byte ReadByte() - { - if (pos == end) - throw new BadImageFormatException(); - return buffer[pos++]; - } - - internal byte[] ReadBytes(int count) - { - if (count < 0) - throw new BadImageFormatException(); - if (end - pos < count) - throw new BadImageFormatException(); - byte[] buf = new byte[count]; - Buffer.BlockCopy(buffer, pos, buf, 0, count); - pos += count; - return buf; - } - - internal int ReadCompressedInt() - { - byte b1 = ReadByte(); - if (b1 <= 0x7F) - { - return b1; - } - else if ((b1 & 0xC0) == 0x80) - { - byte b2 = ReadByte(); - return ((b1 & 0x3F) << 8) | b2; - } - else - { - byte b2 = ReadByte(); - byte b3 = ReadByte(); - byte b4 = ReadByte(); - return ((b1 & 0x3F) << 24) + (b2 << 16) + (b3 << 8) + b4; - } - } - - internal string ReadString() - { - if (PeekByte() == 0xFF) - { - pos++; - return null; - } - int length = ReadCompressedInt(); - string str = Encoding.UTF8.GetString(buffer, pos, length); - pos += length; - return str; - } - - internal char ReadChar() - { - return (char)ReadInt16(); - } - - internal sbyte ReadSByte() - { - return (sbyte)ReadByte(); - } - - internal short ReadInt16() - { - if (end - pos < 2) - throw new BadImageFormatException(); - byte b1 = buffer[pos++]; - byte b2 = buffer[pos++]; - return (short)(b1 | (b2 << 8)); - } - - internal ushort ReadUInt16() - { - return (ushort)ReadInt16(); - } - - internal int ReadInt32() - { - if (end - pos < 4) - throw new BadImageFormatException(); - byte b1 = buffer[pos++]; - byte b2 = buffer[pos++]; - byte b3 = buffer[pos++]; - byte b4 = buffer[pos++]; - return (int)(b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)); - } - - internal uint ReadUInt32() - { - return (uint)ReadInt32(); - } - - internal long ReadInt64() - { - ulong lo = ReadUInt32(); - ulong hi = ReadUInt32(); - return (long)(lo | (hi << 32)); - } - - internal ulong ReadUInt64() - { - return (ulong)ReadInt64(); - } - - internal float ReadSingle() - { - return SingleConverter.Int32BitsToSingle(ReadInt32()); - } - - internal double ReadDouble() - { - return BitConverter.Int64BitsToDouble(ReadInt64()); - } - - internal ByteReader Slice(int length) - { - if (end - pos < length) - throw new BadImageFormatException(); - ByteReader br = new ByteReader(buffer, pos, length); - pos += length; - return br; - } - - // NOTE this method only works if the original offset was aligned and for alignments that are a power of 2 - internal void Align(int alignment) - { - alignment--; - pos = (pos + alignment) & ~alignment; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/EventInfoImpl.cs b/mcs/class/IKVM.Reflection/Reader/EventInfoImpl.cs deleted file mode 100644 index 68d0bc01171..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/EventInfoImpl.cs +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class EventInfoImpl : EventInfo - { - private readonly ModuleReader module; - private readonly Type declaringType; - private readonly int index; - private bool isPublic; - private bool isNonPrivate; - private bool isStatic; - private bool flagsCached; - - internal EventInfoImpl(ModuleReader module, Type declaringType, int index) - { - this.module = module; - this.declaringType = declaringType; - this.index = index; - } - - public override bool Equals(object obj) - { - EventInfoImpl other = obj as EventInfoImpl; - return other != null && other.declaringType == declaringType && other.index == index; - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() * 123 + index; - } - - public override EventAttributes Attributes - { - get { return (EventAttributes)module.Event.records[index].EventFlags; } - } - - public override MethodInfo GetAddMethod(bool nonPublic) - { - return module.MethodSemantics.GetMethod(module, this.MetadataToken, nonPublic, MethodSemanticsTable.AddOn); - } - - public override MethodInfo GetRaiseMethod(bool nonPublic) - { - return module.MethodSemantics.GetMethod(module, this.MetadataToken, nonPublic, MethodSemanticsTable.Fire); - } - - public override MethodInfo GetRemoveMethod(bool nonPublic) - { - return module.MethodSemantics.GetMethod(module, this.MetadataToken, nonPublic, MethodSemanticsTable.RemoveOn); - } - - public override MethodInfo[] GetOtherMethods(bool nonPublic) - { - return module.MethodSemantics.GetMethods(module, this.MetadataToken, nonPublic, MethodSemanticsTable.Other); - } - - public override MethodInfo[] __GetMethods() - { - return module.MethodSemantics.GetMethods(module, this.MetadataToken, true, -1); - } - - public override Type EventHandlerType - { - get { return module.ResolveType(module.Event.records[index].EventType, declaringType); } - } - - public override string Name - { - get { return module.GetString(module.Event.records[index].Name); } - } - - public override Type DeclaringType - { - get { return declaringType; } - } - - public override Module Module - { - get { return module; } - } - - public override int MetadataToken - { - get { return (EventTable.Index << 24) + index + 1; } - } - - internal override bool IsPublic - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isPublic; - } - } - - internal override bool IsNonPrivate - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isNonPrivate; - } - } - - internal override bool IsStatic - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isStatic; - } - } - - private void ComputeFlags() - { - module.MethodSemantics.ComputeFlags(module, this.MetadataToken, out isPublic, out isNonPrivate, out isStatic); - flagsCached = true; - } - - internal override bool IsBaked - { - get { return true; } - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/Field.cs b/mcs/class/IKVM.Reflection/Reader/Field.cs deleted file mode 100644 index 2aba2926b42..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/Field.cs +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class FieldDefImpl : FieldInfo - { - private readonly ModuleReader module; - private readonly TypeDefImpl declaringType; - private readonly int index; - private FieldSignature lazyFieldSig; - - internal FieldDefImpl(ModuleReader module, TypeDefImpl declaringType, int index) - { - this.module = module; - this.declaringType = declaringType; - this.index = index; - } - - public override FieldAttributes Attributes - { - get { return (FieldAttributes)module.Field.records[index].Flags; } - } - - public override Type DeclaringType - { - get { return declaringType.IsModulePseudoType ? null : declaringType; } - } - - public override string Name - { - get { return module.GetString(module.Field.records[index].Name); } - } - - public override string ToString() - { - return this.FieldType.Name + " " + this.Name; - } - - public override Module Module - { - get { return module; } - } - - public override int MetadataToken - { - get { return (FieldTable.Index << 24) + index + 1; } - } - - public override object GetRawConstantValue() - { - return module.Constant.GetRawConstantValue(module, this.MetadataToken); - } - - public override void __GetDataFromRVA(byte[] data, int offset, int length) - { - int rva = this.__FieldRVA; - if (rva == 0) - { - // C++ assemblies can have fields that have an RVA that is zero - Array.Clear(data, offset, length); - return; - } - module.__ReadDataFromRVA(rva, data, offset, length); - } - - public override int __FieldRVA - { - get - { - foreach (int i in module.FieldRVA.Filter(index + 1)) - { - return module.FieldRVA.records[i].RVA; - } - throw new InvalidOperationException(); - } - } - - public override bool __TryGetFieldOffset(out int offset) - { - foreach (int i in this.Module.FieldLayout.Filter(index + 1)) - { - offset = this.Module.FieldLayout.records[i].Offset; - return true; - } - offset = 0; - return false; - } - - internal override FieldSignature FieldSignature - { - get { return lazyFieldSig ?? (lazyFieldSig = FieldSignature.ReadSig(module, module.GetBlob(module.Field.records[index].Signature), declaringType)); } - } - - internal override int ImportTo(Emit.ModuleBuilder module) - { - return module.ImportMethodOrField(declaringType, this.Name, this.FieldSignature); - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - - internal override bool IsBaked - { - get { return true; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/GenericTypeParameter.cs b/mcs/class/IKVM.Reflection/Reader/GenericTypeParameter.cs deleted file mode 100644 index d0c74052154..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/GenericTypeParameter.cs +++ /dev/null @@ -1,403 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - abstract class TypeParameterType : TypeInfo - { - public sealed override string AssemblyQualifiedName - { - get { return null; } - } - - public sealed override bool IsValueType - { - get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; } - } - - public sealed override Type BaseType - { - get - { - foreach (Type type in GetGenericParameterConstraints()) - { - if (!type.IsInterface && !type.IsGenericParameter) - { - return type; - } - } - return this.IsValueType ? this.Module.universe.System_ValueType : this.Module.universe.System_Object; - } - } - - public override Type[] __GetDeclaredInterfaces() - { - List list = new List(); - foreach (Type type in GetGenericParameterConstraints()) - { - if (type.IsInterface) - { - list.Add(type); - } - } - return list.ToArray(); - } - - public sealed override TypeAttributes Attributes - { - get { return TypeAttributes.Public; } - } - - public sealed override string FullName - { - get { return null; } - } - - public sealed override string ToString() - { - return this.Name; - } - - public sealed override bool IsGenericParameter - { - get { return true; } - } - - public sealed override bool __ContainsMissingType - { - get - { - bool freeList = false; - try - { - foreach (Type type in GetGenericParameterConstraints()) - { - if (type.__IsMissing) - { - return true; - } - else if (type.IsConstructedGenericType || type.HasElementType || type.__IsFunctionPointer) - { - // if a constructed type contains generic parameters, - // it might contain this type parameter again and - // to prevent infinite recurssion, we keep a thread local - // list of type parameters we've already processed - if (type.ContainsGenericParameters) - { - if (containsMissingTypeHack == null) - { - freeList = true; - containsMissingTypeHack = new List(); - } - else if (containsMissingTypeHack.Contains(this)) - { - return false; - } - containsMissingTypeHack.Add(this); - } - if (type.__ContainsMissingType) - { - return true; - } - } - } - return false; - } - finally - { - if (freeList) - { - containsMissingTypeHack = null; - } - } - } - } - - [ThreadStatic] - private static List containsMissingTypeHack; - } - - sealed class UnboundGenericMethodParameter : TypeParameterType - { - private static readonly DummyModule module = new DummyModule(); - private readonly int position; - - private sealed class DummyModule : NonPEModule - { - internal DummyModule() - : base(new Universe()) - { - } - - protected override Exception NotSupportedException() - { - return new InvalidOperationException(); - } - - protected override Exception ArgumentOutOfRangeException() - { - return new InvalidOperationException(); - } - - public override bool Equals(object obj) - { - throw new InvalidOperationException(); - } - - public override int GetHashCode() - { - throw new InvalidOperationException(); - } - - public override string ToString() - { - throw new InvalidOperationException(); - } - - public override int MDStreamVersion - { - get { throw new InvalidOperationException(); } - } - - public override Assembly Assembly - { - get { throw new InvalidOperationException(); } - } - - internal override Type FindType(TypeName typeName) - { - throw new InvalidOperationException(); - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - throw new InvalidOperationException(); - } - - internal override void GetTypesImpl(List list) - { - throw new InvalidOperationException(); - } - - public override string FullyQualifiedName - { - get { throw new InvalidOperationException(); } - } - - public override string Name - { - get { throw new InvalidOperationException(); } - } - - public override Guid ModuleVersionId - { - get { throw new InvalidOperationException(); } - } - - public override string ScopeName - { - get { throw new InvalidOperationException(); } - } - } - - internal static Type Make(int position) - { - return module.universe.CanonicalizeType(new UnboundGenericMethodParameter(position)); - } - - private UnboundGenericMethodParameter(int position) - { - this.position = position; - } - - public override bool Equals(object obj) - { - UnboundGenericMethodParameter other = obj as UnboundGenericMethodParameter; - return other != null && other.position == position; - } - - public override int GetHashCode() - { - return position; - } - - public override string Namespace - { - get { throw new InvalidOperationException(); } - } - - public override string Name - { - get { throw new InvalidOperationException(); } - } - - public override int MetadataToken - { - get { throw new InvalidOperationException(); } - } - - public override Module Module - { - get { return module; } - } - - public override int GenericParameterPosition - { - get { return position; } - } - - public override Type DeclaringType - { - get { return null; } - } - - public override MethodBase DeclaringMethod - { - get { throw new InvalidOperationException(); } - } - - public override Type[] GetGenericParameterConstraints() - { - throw new InvalidOperationException(); - } - - public override GenericParameterAttributes GenericParameterAttributes - { - get { throw new InvalidOperationException(); } - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - return binder.BindMethodParameter(this); - } - - internal override bool IsBaked - { - get { throw new InvalidOperationException(); } - } - } - - sealed class GenericTypeParameter : TypeParameterType - { - private readonly ModuleReader module; - private readonly int index; - - internal GenericTypeParameter(ModuleReader module, int index) - { - this.module = module; - this.index = index; - } - - public override bool Equals(object obj) - { - return base.Equals(obj); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public override string Namespace - { - get { return DeclaringType.Namespace; } - } - - public override string Name - { - get { return module.GetString(module.GenericParam.records[index].Name); } - } - - public override Module Module - { - get { return module; } - } - - public override int MetadataToken - { - get { return (GenericParamTable.Index << 24) + index + 1; } - } - - public override int GenericParameterPosition - { - get { return module.GenericParam.records[index].Number; } - } - - public override Type DeclaringType - { - get - { - int owner = module.GenericParam.records[index].Owner; - return (owner >> 24) == TypeDefTable.Index ? module.ResolveType(owner) : null; - } - } - - public override MethodBase DeclaringMethod - { - get - { - int owner = module.GenericParam.records[index].Owner; - return (owner >> 24) == MethodDefTable.Index ? module.ResolveMethod(owner) : null; - } - } - - public override Type[] GetGenericParameterConstraints() - { - IGenericContext context = (this.DeclaringMethod as IGenericContext) ?? this.DeclaringType; - List list = new List(); - foreach (int i in module.GenericParamConstraint.Filter(this.MetadataToken)) - { - list.Add(module.ResolveType(module.GenericParamConstraint.records[i].Constraint, context)); - } - return list.ToArray(); - } - - public override GenericParameterAttributes GenericParameterAttributes - { - get { return (GenericParameterAttributes)module.GenericParam.records[index].Flags; } - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - int owner = module.GenericParam.records[index].Owner; - if ((owner >> 24) == MethodDefTable.Index) - { - return binder.BindMethodParameter(this); - } - else - { - return binder.BindTypeParameter(this); - } - } - - internal override bool IsBaked - { - get { return true; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/MetadataReader.cs b/mcs/class/IKVM.Reflection/Reader/MetadataReader.cs deleted file mode 100644 index 28a4720d9bd..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/MetadataReader.cs +++ /dev/null @@ -1,406 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class MetadataReader : MetadataRW - { - private readonly Stream stream; - private const int bufferLength = 2048; - private readonly byte[] buffer = new byte[bufferLength]; - private int pos = bufferLength; - - internal MetadataReader(ModuleReader module, Stream stream, byte heapSizes) - : base(module, (heapSizes & 0x01) != 0, (heapSizes & 0x02) != 0, (heapSizes & 0x04) != 0) - { - this.stream = stream; - } - - private void FillBuffer(int needed) - { - int count = bufferLength - pos; - if (count != 0) - { - // move remaining bytes to the front of the buffer - Buffer.BlockCopy(buffer, pos, buffer, 0, count); - } - pos = 0; - - while (count < needed) - { - int len = stream.Read(buffer, count, bufferLength - count); - if (len == 0) - { - throw new BadImageFormatException(); - } - count += len; - } - - if (count != bufferLength) - { - // we didn't fill the buffer completely, so have to restore the invariant - // that all data from pos up until the end of the buffer is valid - Buffer.BlockCopy(buffer, 0, buffer, bufferLength - count, count); - pos = bufferLength - count; - } - } - - internal ushort ReadUInt16() - { - return (ushort)ReadInt16(); - } - - internal short ReadInt16() - { - if (pos > bufferLength - 2) - { - FillBuffer(2); - } - byte b1 = buffer[pos++]; - byte b2 = buffer[pos++]; - return (short)(b1 | (b2 << 8)); - } - - internal int ReadInt32() - { - if (pos > bufferLength - 4) - { - FillBuffer(4); - } - byte b1 = buffer[pos++]; - byte b2 = buffer[pos++]; - byte b3 = buffer[pos++]; - byte b4 = buffer[pos++]; - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); - } - - private int ReadIndex(bool big) - { - if (big) - { - return ReadInt32(); - } - else - { - return ReadUInt16(); - } - } - - internal int ReadStringIndex() - { - return ReadIndex(bigStrings); - } - - internal int ReadGuidIndex() - { - return ReadIndex(bigGuids); - } - - internal int ReadBlobIndex() - { - return ReadIndex(bigBlobs); - } - - internal int ReadResolutionScope() - { - int codedIndex = ReadIndex(bigResolutionScope); - switch (codedIndex & 3) - { - case 0: - return (ModuleTable.Index << 24) + (codedIndex >> 2); - case 1: - return (ModuleRefTable.Index << 24) + (codedIndex >> 2); - case 2: - return (AssemblyRefTable.Index << 24) + (codedIndex >> 2); - case 3: - return (TypeRefTable.Index << 24) + (codedIndex >> 2); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadTypeDefOrRef() - { - int codedIndex = ReadIndex(bigTypeDefOrRef); - switch (codedIndex & 3) - { - case 0: - return (TypeDefTable.Index << 24) + (codedIndex >> 2); - case 1: - return (TypeRefTable.Index << 24) + (codedIndex >> 2); - case 2: - return (TypeSpecTable.Index << 24) + (codedIndex >> 2); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadMemberRefParent() - { - int codedIndex = ReadIndex(bigMemberRefParent); - switch (codedIndex & 7) - { - case 0: - return (TypeDefTable.Index << 24) + (codedIndex >> 3); - case 1: - return (TypeRefTable.Index << 24) + (codedIndex >> 3); - case 2: - return (ModuleRefTable.Index << 24) + (codedIndex >> 3); - case 3: - return (MethodDefTable.Index << 24) + (codedIndex >> 3); - case 4: - return (TypeSpecTable.Index << 24) + (codedIndex >> 3); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadHasCustomAttribute() - { - int codedIndex = ReadIndex(bigHasCustomAttribute); - switch (codedIndex & 31) - { - case 0: - return (MethodDefTable.Index << 24) + (codedIndex >> 5); - case 1: - return (FieldTable.Index << 24) + (codedIndex >> 5); - case 2: - return (TypeRefTable.Index << 24) + (codedIndex >> 5); - case 3: - return (TypeDefTable.Index << 24) + (codedIndex >> 5); - case 4: - return (ParamTable.Index << 24) + (codedIndex >> 5); - case 5: - return (InterfaceImplTable.Index << 24) + (codedIndex >> 5); - case 6: - return (MemberRefTable.Index << 24) + (codedIndex >> 5); - case 7: - return (ModuleTable.Index << 24) + (codedIndex >> 5); - case 8: - throw new BadImageFormatException(); - case 9: - return (PropertyTable.Index << 24) + (codedIndex >> 5); - case 10: - return (EventTable.Index << 24) + (codedIndex >> 5); - case 11: - return (StandAloneSigTable.Index << 24) + (codedIndex >> 5); - case 12: - return (ModuleRefTable.Index << 24) + (codedIndex >> 5); - case 13: - return (TypeSpecTable.Index << 24) + (codedIndex >> 5); - case 14: - return (AssemblyTable.Index << 24) + (codedIndex >> 5); - case 15: - return (AssemblyRefTable.Index << 24) + (codedIndex >> 5); - case 16: - return (FileTable.Index << 24) + (codedIndex >> 5); - case 17: - return (ExportedTypeTable.Index << 24) + (codedIndex >> 5); - case 18: - return (ManifestResourceTable.Index << 24) + (codedIndex >> 5); - case 19: - return (GenericParamTable.Index << 24) + (codedIndex >> 5); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadCustomAttributeType() - { - int codedIndex = ReadIndex(bigCustomAttributeType); - switch (codedIndex & 7) - { - case 2: - return (MethodDefTable.Index << 24) + (codedIndex >> 3); - case 3: - return (MemberRefTable.Index << 24) + (codedIndex >> 3); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadMethodDefOrRef() - { - int codedIndex = ReadIndex(bigMethodDefOrRef); - switch (codedIndex & 1) - { - case 0: - return (MethodDefTable.Index << 24) + (codedIndex >> 1); - case 1: - return (MemberRefTable.Index << 24) + (codedIndex >> 1); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadHasConstant() - { - int codedIndex = ReadIndex(bigHasConstant); - switch (codedIndex & 3) - { - case 0: - return (FieldTable.Index << 24) + (codedIndex >> 2); - case 1: - return (ParamTable.Index << 24) + (codedIndex >> 2); - case 2: - return (PropertyTable.Index << 24) + (codedIndex >> 2); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadHasSemantics() - { - int codedIndex = ReadIndex(bigHasSemantics); - switch (codedIndex & 1) - { - case 0: - return (EventTable.Index << 24) + (codedIndex >> 1); - case 1: - return (PropertyTable.Index << 24) + (codedIndex >> 1); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadHasFieldMarshal() - { - int codedIndex = ReadIndex(bigHasFieldMarshal); - switch (codedIndex & 1) - { - case 0: - return (FieldTable.Index << 24) + (codedIndex >> 1); - case 1: - return (ParamTable.Index << 24) + (codedIndex >> 1); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadHasDeclSecurity() - { - int codedIndex = ReadIndex(bigHasDeclSecurity); - switch (codedIndex & 3) - { - case 0: - return (TypeDefTable.Index << 24) + (codedIndex >> 2); - case 1: - return (MethodDefTable.Index << 24) + (codedIndex >> 2); - case 2: - return (AssemblyTable.Index << 24) + (codedIndex >> 2); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadTypeOrMethodDef() - { - int codedIndex = ReadIndex(bigTypeOrMethodDef); - switch (codedIndex & 1) - { - case 0: - return (TypeDefTable.Index << 24) + (codedIndex >> 1); - case 1: - return (MethodDefTable.Index << 24) + (codedIndex >> 1); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadMemberForwarded() - { - int codedIndex = ReadIndex(bigMemberForwarded); - switch (codedIndex & 1) - { - case 0: - return (FieldTable.Index << 24) + (codedIndex >> 1); - case 1: - return (MethodDefTable.Index << 24) + (codedIndex >> 1); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadImplementation() - { - int codedIndex = ReadIndex(bigImplementation); - switch (codedIndex & 3) - { - case 0: - return (FileTable.Index << 24) + (codedIndex >> 2); - case 1: - return (AssemblyRefTable.Index << 24) + (codedIndex >> 2); - case 2: - return (ExportedTypeTable.Index << 24) + (codedIndex >> 2); - default: - throw new BadImageFormatException(); - } - } - - internal int ReadField() - { - return ReadIndex(bigField); - } - - internal int ReadMethodDef() - { - return ReadIndex(bigMethodDef); - } - - internal int ReadParam() - { - return ReadIndex(bigParam); - } - - internal int ReadProperty() - { - return ReadIndex(bigProperty); - } - - internal int ReadEvent() - { - return ReadIndex(bigEvent); - } - - internal int ReadTypeDef() - { - return ReadIndex(bigTypeDef) | (TypeDefTable.Index << 24); - } - - internal int ReadGenericParam() - { - return ReadIndex(bigGenericParam) | (GenericParamTable.Index << 24); - } - - internal int ReadModuleRef() - { - return ReadIndex(bigModuleRef) | (ModuleRefTable.Index << 24); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/Method.cs b/mcs/class/IKVM.Reflection/Reader/Method.cs deleted file mode 100644 index dd2712ea3a7..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/Method.cs +++ /dev/null @@ -1,394 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class MethodDefImpl : MethodInfo - { - private readonly ModuleReader module; - private readonly int index; - private readonly TypeDefImpl declaringType; - private MethodSignature lazyMethodSignature; - private ParameterInfo returnParameter; - private ParameterInfo[] parameters; - private Type[] typeArgs; - - internal MethodDefImpl(ModuleReader module, TypeDefImpl declaringType, int index) - { - this.module = module; - this.index = index; - this.declaringType = declaringType; - } - - public override MethodBody GetMethodBody() - { - return GetMethodBody(this); - } - - internal MethodBody GetMethodBody(IGenericContext context) - { - if ((GetMethodImplementationFlags() & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL) - { - // method is not IL - return null; - } - int rva = module.MethodDef.records[index].RVA; - return rva == 0 ? null : new MethodBody(module, rva, context); - } - - public override int __MethodRVA - { - get { return module.MethodDef.records[index].RVA; } - } - - public override CallingConventions CallingConvention - { - get { return this.MethodSignature.CallingConvention; } - } - - public override MethodAttributes Attributes - { - get { return (MethodAttributes)module.MethodDef.records[index].Flags; } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return (MethodImplAttributes)module.MethodDef.records[index].ImplFlags; - } - - public override ParameterInfo[] GetParameters() - { - PopulateParameters(); - return (ParameterInfo[])parameters.Clone(); - } - - private void PopulateParameters() - { - if (parameters == null) - { - MethodSignature methodSignature = this.MethodSignature; - parameters = new ParameterInfo[methodSignature.GetParameterCount()]; - int parameter = module.MethodDef.records[index].ParamList - 1; - int end = module.MethodDef.records.Length > index + 1 ? module.MethodDef.records[index + 1].ParamList - 1 : module.Param.records.Length; - for (; parameter < end; parameter++) - { - int seq = module.Param.records[parameter].Sequence - 1; - if (seq == -1) - { - returnParameter = new ParameterInfoImpl(this, seq, parameter); - } - else - { - parameters[seq] = new ParameterInfoImpl(this, seq, parameter); - } - } - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i] == null) - { - parameters[i] = new ParameterInfoImpl(this, i, -1); - } - } - if (returnParameter == null) - { - returnParameter = new ParameterInfoImpl(this, -1, -1); - } - } - } - - internal override int ParameterCount - { - get { return this.MethodSignature.GetParameterCount(); } - } - - public override ParameterInfo ReturnParameter - { - get - { - PopulateParameters(); - return returnParameter; - } - } - - public override Type ReturnType - { - get - { - return this.ReturnParameter.ParameterType; - } - } - - public override Type DeclaringType - { - get { return declaringType.IsModulePseudoType ? null : declaringType; } - } - - public override string Name - { - get { return module.GetString(module.MethodDef.records[index].Name); } - } - - public override int MetadataToken - { - get { return (MethodDefTable.Index << 24) + index + 1; } - } - - public override bool IsGenericMethodDefinition - { - get - { - PopulateGenericArguments(); - return typeArgs.Length > 0; - } - } - - public override bool IsGenericMethod - { - get { return IsGenericMethodDefinition; } - } - - public override Type[] GetGenericArguments() - { - PopulateGenericArguments(); - return Util.Copy(typeArgs); - } - - private void PopulateGenericArguments() - { - if (typeArgs == null) - { - int token = this.MetadataToken; - int first = module.GenericParam.FindFirstByOwner(token); - if (first == -1) - { - typeArgs = Type.EmptyTypes; - } - else - { - List list = new List(); - int len = module.GenericParam.records.Length; - for (int i = first; i < len && module.GenericParam.records[i].Owner == token; i++) - { - list.Add(new GenericTypeParameter(module, i)); - } - typeArgs = list.ToArray(); - } - } - } - - internal override Type GetGenericMethodArgument(int index) - { - PopulateGenericArguments(); - return typeArgs[index]; - } - - internal override int GetGenericMethodArgumentCount() - { - PopulateGenericArguments(); - return typeArgs.Length; - } - - public override MethodInfo GetGenericMethodDefinition() - { - if (this.IsGenericMethodDefinition) - { - return this; - } - throw new InvalidOperationException(); - } - - public override MethodInfo MakeGenericMethod(params Type[] typeArguments) - { - return new GenericMethodInstance(declaringType, this, typeArguments); - } - - public override Module Module - { - get { return module; } - } - - internal override MethodSignature MethodSignature - { - get { return lazyMethodSignature ?? (lazyMethodSignature = MethodSignature.ReadSig(module, module.GetBlob(module.MethodDef.records[index].Signature), this)); } - } - - internal override int ImportTo(Emit.ModuleBuilder module) - { - return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature); - } - - public override MethodInfo[] __GetMethodImpls() - { - Type[] typeArgs = null; - List list = null; - foreach (int i in module.MethodImpl.Filter(declaringType.MetadataToken)) - { - if (module.MethodImpl.records[i].MethodBody == this.MetadataToken) - { - if (typeArgs == null) - { - typeArgs = declaringType.GetGenericArguments(); - } - if (list == null) - { - list = new List(); - } - list.Add((MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null)); - } - } - return Util.ToArray(list, Empty.Array); - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - - internal override bool IsBaked - { - get { return true; } - } - } - - sealed class ParameterInfoImpl : ParameterInfo - { - private readonly MethodDefImpl method; - private readonly int position; - private readonly int index; - - internal ParameterInfoImpl(MethodDefImpl method, int position, int index) - { - this.method = method; - this.position = position; - this.index = index; - } - - public override string Name - { - get { return index == -1 ? null : ((ModuleReader)this.Module).GetString(this.Module.Param.records[index].Name); } - } - - public override Type ParameterType - { - get { return position == -1 ? method.MethodSignature.GetReturnType(method) : method.MethodSignature.GetParameterType(method, position); } - } - - public override ParameterAttributes Attributes - { - get { return index == -1 ? ParameterAttributes.None : (ParameterAttributes)this.Module.Param.records[index].Flags; } - } - - public override int Position - { - get { return position; } - } - - public override object RawDefaultValue - { - get - { - if ((this.Attributes & ParameterAttributes.HasDefault) != 0) - { - return this.Module.Constant.GetRawConstantValue(this.Module, this.MetadataToken); - } - Universe universe = this.Module.universe; - if (this.ParameterType == universe.System_Decimal) - { - Type attr = universe.System_Runtime_CompilerServices_DecimalConstantAttribute; - if (attr != null) - { - foreach (CustomAttributeData cad in CustomAttributeData.__GetCustomAttributes(this, attr, false)) - { - IList args = cad.ConstructorArguments; - if (args.Count == 5) - { - if (args[0].ArgumentType == universe.System_Byte - && args[1].ArgumentType == universe.System_Byte - && args[2].ArgumentType == universe.System_Int32 - && args[3].ArgumentType == universe.System_Int32 - && args[4].ArgumentType == universe.System_Int32) - { - return new Decimal((int)args[4].Value, (int)args[3].Value, (int)args[2].Value, (byte)args[1].Value != 0, (byte)args[0].Value); - } - else if (args[0].ArgumentType == universe.System_Byte - && args[1].ArgumentType == universe.System_Byte - && args[2].ArgumentType == universe.System_UInt32 - && args[3].ArgumentType == universe.System_UInt32 - && args[4].ArgumentType == universe.System_UInt32) - { - return new Decimal(unchecked((int)(uint)args[4].Value), unchecked((int)(uint)args[3].Value), unchecked((int)(uint)args[2].Value), (byte)args[1].Value != 0, (byte)args[0].Value); - } - } - } - } - } - if ((this.Attributes & ParameterAttributes.Optional) != 0) - { - return Missing.Value; - } - return null; - } - } - - public override CustomModifiers __GetCustomModifiers() - { - return position == -1 - ? method.MethodSignature.GetReturnTypeCustomModifiers(method) - : method.MethodSignature.GetParameterCustomModifiers(method, position); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - return FieldMarshal.ReadFieldMarshal(this.Module, this.MetadataToken, out fieldMarshal); - } - - public override MemberInfo Member - { - get - { - // return the right ConstructorInfo wrapper - return method.Module.ResolveMethod(method.MetadataToken); - } - } - - public override int MetadataToken - { - get - { - // for parameters that don't have a row in the Param table, we return 0x08000000 (because index is -1 in that case), - // just like .NET - return (ParamTable.Index << 24) + index + 1; - } - } - - internal override Module Module - { - get { return method.Module; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/ModuleReader.cs b/mcs/class/IKVM.Reflection/Reader/ModuleReader.cs deleted file mode 100644 index 180e9689eef..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/ModuleReader.cs +++ /dev/null @@ -1,1269 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using System.Text; -using System.Collections.Generic; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class StreamHeader - { - internal uint Offset; - internal uint Size; - internal string Name; - - internal void Read(BinaryReader br) - { - Offset = br.ReadUInt32(); - Size = br.ReadUInt32(); - byte[] buf = new byte[32]; - byte b; - int len = 0; - while ((b = br.ReadByte()) != 0) - { - buf[len++] = b; - } - Name = Encoding.UTF8.GetString(buf, 0, len); ; - int padding = -1 + ((len + 4) & ~3) - len; - br.BaseStream.Seek(padding, SeekOrigin.Current); - } - } - - sealed class ModuleReader : Module - { - internal readonly Stream stream; - private readonly string location; - private Assembly assembly; - private readonly PEReader peFile = new PEReader(); - private readonly CliHeader cliHeader = new CliHeader(); - private string imageRuntimeVersion; - private int metadataStreamVersion; - private byte[] stringHeap; - private byte[] blobHeap; - private byte[] userStringHeap; - private byte[] guidHeap; - private TypeDefImpl[] typeDefs; - private TypeDefImpl moduleType; - private Assembly[] assemblyRefs; - private Type[] typeRefs; - private Type[] typeSpecs; - private FieldInfo[] fields; - private MethodBase[] methods; - private MemberInfo[] memberRefs; - private Dictionary strings = new Dictionary(); - private Dictionary types = new Dictionary(); - private Dictionary forwardedTypes = new Dictionary(); - - private sealed class LazyForwardedType - { - private readonly int assemblyRef; - private Type type; - - internal LazyForwardedType(int assemblyRef) - { - this.assemblyRef = assemblyRef; - } - - internal Type GetType(ModuleReader module, TypeName typeName) - { - if (type == null) - { - Assembly asm = module.ResolveAssemblyRef(assemblyRef); - type = asm.ResolveType(typeName); - if (type == null) - { - throw new TypeLoadException(typeName.ToString()); - } - } - return type; - } - } - - internal ModuleReader(AssemblyReader assembly, Universe universe, Stream stream, string location) - : base(universe) - { - this.stream = stream; - this.location = location; - Read(); - if (assembly == null && AssemblyTable.records.Length != 0) - { - assembly = new AssemblyReader(location, this); - } - this.assembly = assembly; - } - - private void Read() - { - BinaryReader br = new BinaryReader(stream); - peFile.Read(br); - stream.Seek(peFile.RvaToFileOffset(peFile.GetComDescriptorVirtualAddress()), SeekOrigin.Begin); - cliHeader.Read(br); - stream.Seek(peFile.RvaToFileOffset(cliHeader.MetaData.VirtualAddress), SeekOrigin.Begin); - foreach (StreamHeader sh in ReadStreamHeaders(br, out imageRuntimeVersion)) - { - switch (sh.Name) - { - case "#Strings": - stringHeap = ReadHeap(stream, sh); - break; - case "#Blob": - blobHeap = ReadHeap(stream, sh); - break; - case "#US": - userStringHeap = ReadHeap(stream, sh); - break; - case "#GUID": - guidHeap = ReadHeap(stream, sh); - break; - case "#~": - case "#-": - stream.Seek(peFile.RvaToFileOffset(cliHeader.MetaData.VirtualAddress + sh.Offset), SeekOrigin.Begin); - ReadTables(br); - break; - default: - // we ignore unknown streams, because the CLR does so too - // (and some obfuscators add bogus streams) - break; - } - } - } - - internal void SetAssembly(Assembly assembly) - { - this.assembly = assembly; - } - - private static StreamHeader[] ReadStreamHeaders(BinaryReader br, out string Version) - { - uint Signature = br.ReadUInt32(); - if (Signature != 0x424A5342) - { - throw new BadImageFormatException("Invalid metadata signature"); - } - /*ushort MajorVersion =*/ br.ReadUInt16(); - /*ushort MinorVersion =*/ br.ReadUInt16(); - /*uint Reserved =*/ br.ReadUInt32(); - uint Length = br.ReadUInt32(); - byte[] buf = br.ReadBytes((int)Length); - Version = Encoding.UTF8.GetString(buf).TrimEnd('\u0000'); - /*ushort Flags =*/ br.ReadUInt16(); - ushort Streams = br.ReadUInt16(); - StreamHeader[] streamHeaders = new StreamHeader[Streams]; - for (int i = 0; i < streamHeaders.Length; i++) - { - streamHeaders[i] = new StreamHeader(); - streamHeaders[i].Read(br); - } - return streamHeaders; - } - - private void ReadTables(BinaryReader br) - { - Table[] tables = GetTables(); - /*uint Reserved0 =*/ br.ReadUInt32(); - byte MajorVersion = br.ReadByte(); - byte MinorVersion = br.ReadByte(); - metadataStreamVersion = MajorVersion << 16 | MinorVersion; - byte HeapSizes = br.ReadByte(); - /*byte Reserved7 =*/ br.ReadByte(); - ulong Valid = br.ReadUInt64(); - ulong Sorted = br.ReadUInt64(); - for (int i = 0; i < 64; i++) - { - if ((Valid & (1UL << i)) != 0) - { - tables[i].Sorted = (Sorted & (1UL << i)) != 0; - tables[i].RowCount = br.ReadInt32(); - } - else if (tables[i] != null) - { - tables[i].RowCount = 0; - } - } - MetadataReader mr = new MetadataReader(this, br.BaseStream, HeapSizes); - for (int i = 0; i < 64; i++) - { - if ((Valid & (1UL << i)) != 0) - { - tables[i].Read(mr); - } - } - if (ParamPtr.RowCount != 0) - { - throw new NotImplementedException("ParamPtr table support has not yet been implemented."); - } - } - - private byte[] ReadHeap(Stream stream, StreamHeader sh) - { - byte[] buf = new byte[sh.Size]; - stream.Seek(peFile.RvaToFileOffset(cliHeader.MetaData.VirtualAddress + sh.Offset), SeekOrigin.Begin); - for (int pos = 0; pos < buf.Length; ) - { - int read = stream.Read(buf, pos, buf.Length - pos); - if (read == 0) - { - throw new BadImageFormatException(); - } - pos += read; - } - return buf; - } - - internal void SeekRVA(int rva) - { - stream.Seek(peFile.RvaToFileOffset((uint)rva), SeekOrigin.Begin); - } - - internal override void GetTypesImpl(List list) - { - PopulateTypeDef(); - foreach (TypeDefImpl type in typeDefs) - { - if (type != moduleType) - { - list.Add(type); - } - } - } - - private void PopulateTypeDef() - { - if (typeDefs == null) - { - typeDefs = new TypeDefImpl[TypeDef.records.Length]; - for (int i = 0; i < typeDefs.Length; i++) - { - TypeDefImpl type = new TypeDefImpl(this, i); - typeDefs[i] = type; - if (type.IsModulePseudoType) - { - moduleType = type; - } - else if (!type.IsNestedByFlags) - { - types.Add(new TypeName(type.__Namespace, type.__Name), type); - } - } - // add forwarded types to forwardedTypes dictionary (because Module.GetType(string) should return them) - for (int i = 0; i < ExportedType.records.Length; i++) - { - int implementation = ExportedType.records[i].Implementation; - if (implementation >> 24 == AssemblyRefTable.Index) - { - TypeName typeName = GetTypeName(ExportedType.records[i].TypeNamespace, ExportedType.records[i].TypeName); - forwardedTypes.Add(typeName, new LazyForwardedType((implementation & 0xFFFFFF) - 1)); - } - } - } - } - - internal override string GetString(int index) - { - if (index == 0) - { - return null; - } - string str; - if (!strings.TryGetValue(index, out str)) - { - int len = 0; - while (stringHeap[index + len] != 0) - { - len++; - } - str = Encoding.UTF8.GetString(stringHeap, index, len); - strings.Add(index, str); - } - return str; - } - - private static int ReadCompressedInt(byte[] buffer, ref int offset) - { - byte b1 = buffer[offset++]; - if (b1 <= 0x7F) - { - return b1; - } - else if ((b1 & 0xC0) == 0x80) - { - byte b2 = buffer[offset++]; - return ((b1 & 0x3F) << 8) | b2; - } - else - { - byte b2 = buffer[offset++]; - byte b3 = buffer[offset++]; - byte b4 = buffer[offset++]; - return ((b1 & 0x3F) << 24) + (b2 << 16) + (b3 << 8) + b4; - } - } - - internal byte[] GetBlobCopy(int blobIndex) - { - int len = ReadCompressedInt(blobHeap, ref blobIndex); - byte[] buf = new byte[len]; - Buffer.BlockCopy(blobHeap, blobIndex, buf, 0, len); - return buf; - } - - internal override ByteReader GetBlob(int blobIndex) - { - return ByteReader.FromBlob(blobHeap, blobIndex); - } - - public override string ResolveString(int metadataToken) - { - string str; - if (!strings.TryGetValue(metadataToken, out str)) - { - if ((metadataToken >> 24) != 0x70) - { - throw TokenOutOfRangeException(metadataToken); - } - int index = metadataToken & 0xFFFFFF; - int len = ReadCompressedInt(userStringHeap, ref index) & ~1; - StringBuilder sb = new StringBuilder(len / 2); - for (int i = 0; i < len; i += 2) - { - char ch = (char)(userStringHeap[index + i] | userStringHeap[index + i + 1] << 8); - sb.Append(ch); - } - str = sb.ToString(); - strings.Add(metadataToken, str); - } - return str; - } - - internal override Type ResolveType(int metadataToken, IGenericContext context) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if (index < 0) - { - throw TokenOutOfRangeException(metadataToken); - } - else if ((metadataToken >> 24) == TypeDefTable.Index && index < TypeDef.RowCount) - { - PopulateTypeDef(); - return typeDefs[index]; - } - else if ((metadataToken >> 24) == TypeRefTable.Index && index < TypeRef.RowCount) - { - if (typeRefs == null) - { - typeRefs = new Type[TypeRef.records.Length]; - } - if (typeRefs[index] == null) - { - int scope = TypeRef.records[index].ResolutionScope; - switch (scope >> 24) - { - case AssemblyRefTable.Index: - { - Assembly assembly = ResolveAssemblyRef((scope & 0xFFFFFF) - 1); - TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); - typeRefs[index] = assembly.ResolveType(typeName); - break; - } - case TypeRefTable.Index: - { - Type outer = ResolveType(scope, null); - TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); - typeRefs[index] = outer.ResolveNestedType(typeName); - break; - } - case ModuleTable.Index: - case ModuleRefTable.Index: - { - Module module; - if (scope >> 24 == ModuleTable.Index) - { - if (scope == 0 || scope == 1) - { - module = this; - } - else - { - throw new NotImplementedException("self reference scope?"); - } - } - else - { - module = ResolveModuleRef(ModuleRef.records[(scope & 0xFFFFFF) - 1]); - } - TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); - typeRefs[index] = module.FindType(typeName) ?? module.universe.GetMissingTypeOrThrow(module, null, typeName); - break; - } - default: - throw new NotImplementedException("ResolutionScope = " + scope.ToString("X")); - } - } - return typeRefs[index]; - } - else if ((metadataToken >> 24) == TypeSpecTable.Index && index < TypeSpec.RowCount) - { - if (typeSpecs == null) - { - typeSpecs = new Type[TypeSpec.records.Length]; - } - Type type = typeSpecs[index]; - if (type == null) - { - TrackingGenericContext tc = context == null ? null : new TrackingGenericContext(context); - type = Signature.ReadTypeSpec(this, ByteReader.FromBlob(blobHeap, TypeSpec.records[index]), tc); - if (tc == null || !tc.IsUsed) - { - typeSpecs[index] = type; - } - } - return type; - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - private Module ResolveModuleRef(int moduleNameIndex) - { - string moduleName = GetString(moduleNameIndex); - Module module = assembly.GetModule(moduleName); - if (module == null) - { - throw new FileNotFoundException(moduleName); - } - return module; - } - - private sealed class TrackingGenericContext : IGenericContext - { - private readonly IGenericContext context; - private bool used; - - internal TrackingGenericContext(IGenericContext context) - { - this.context = context; - } - - internal bool IsUsed - { - get { return used; } - } - - public Type GetGenericTypeArgument(int index) - { - used = true; - return context.GetGenericTypeArgument(index); - } - - public Type GetGenericMethodArgument(int index) - { - used = true; - return context.GetGenericMethodArgument(index); - } - } - - private TypeName GetTypeName(int typeNamespace, int typeName) - { - return new TypeName(GetString(typeNamespace), GetString(typeName)); - } - - internal Assembly ResolveAssemblyRef(int index) - { - if (assemblyRefs == null) - { - assemblyRefs = new Assembly[AssemblyRef.RowCount]; - } - if (assemblyRefs[index] == null) - { - assemblyRefs[index] = ResolveAssemblyRefImpl(ref AssemblyRef.records[index]); - } - return assemblyRefs[index]; - } - - private Assembly ResolveAssemblyRefImpl(ref AssemblyRefTable.Record rec) - { - const int PublicKey = 0x0001; - string name = String.Format("{0}, Version={1}.{2}.{3}.{4}, Culture={5}, {6}={7}", - GetString(rec.Name), - rec.MajorVersion, - rec.MinorVersion, - rec.BuildNumber, - rec.RevisionNumber, - rec.Culture == 0 ? "neutral" : GetString(rec.Culture), - (rec.Flags & PublicKey) == 0 ? "PublicKeyToken" : "PublicKey", - PublicKeyOrTokenToString(rec.PublicKeyOrToken)); - return universe.Load(name, this.Assembly, true); - } - - private string PublicKeyOrTokenToString(int publicKeyOrToken) - { - if (publicKeyOrToken == 0) - { - return "null"; - } - ByteReader br = GetBlob(publicKeyOrToken); - if (br.Length == 0) - { - return "null"; - } - StringBuilder sb = new StringBuilder(br.Length * 2); - while (br.Length > 0) - { - sb.AppendFormat("{0:x2}", br.ReadByte()); - } - return sb.ToString(); - } - - public override Guid ModuleVersionId - { - get - { - byte[] buf = new byte[16]; - Buffer.BlockCopy(guidHeap, 16 * (ModuleTable.records[0].Mvid - 1), buf, 0, 16); - return new Guid(buf); - } - } - - public override string FullyQualifiedName - { - get { return location ?? ""; } - } - - public override string Name - { - get { return location == null ? "" : System.IO.Path.GetFileName(location); } - } - - public override Assembly Assembly - { - get { return assembly; } - } - - internal override Type FindType(TypeName typeName) - { - PopulateTypeDef(); - Type type; - if (!types.TryGetValue(typeName, out type)) - { - LazyForwardedType fw; - if (forwardedTypes.TryGetValue(typeName, out fw)) - { - return fw.GetType(this, typeName); - } - } - return type; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - PopulateTypeDef(); - foreach (Type type in types.Values) - { - if (new TypeName(type.__Namespace, type.__Name).ToLowerInvariant() == lowerCaseName) - { - return type; - } - } - foreach (TypeName name in forwardedTypes.Keys) - { - if (name.ToLowerInvariant() == lowerCaseName) - { - return forwardedTypes[name].GetType(this, name); - } - } - return null; - } - - private Exception TokenOutOfRangeException(int metadataToken) - { - return new ArgumentOutOfRangeException("metadataToken", String.Format("Token 0x{0:x8} is not valid in the scope of module {1}.", metadataToken, this.Name)); - } - - public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - switch (metadataToken >> 24) - { - case FieldTable.Index: - return ResolveField(metadataToken, genericTypeArguments, genericMethodArguments); - case MemberRefTable.Index: - int index = (metadataToken & 0xFFFFFF) - 1; - if (index < 0 || index >= MemberRef.RowCount) - { - goto default; - } - return GetMemberRef(index, genericTypeArguments, genericMethodArguments); - case MethodDefTable.Index: - case MethodSpecTable.Index: - return ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments); - default: - throw TokenOutOfRangeException(metadataToken); - } - } - - internal FieldInfo GetFieldAt(TypeDefImpl owner, int index) - { - if (fields == null) - { - fields = new FieldInfo[Field.records.Length]; - } - if (fields[index] == null) - { - fields[index] = new FieldDefImpl(this, owner ?? FindFieldOwner(index), index); - } - return fields[index]; - } - - public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if (index < 0) - { - throw TokenOutOfRangeException(metadataToken); - } - else if ((metadataToken >> 24) == FieldTable.Index && index < Field.RowCount) - { - return GetFieldAt(null, index); - } - else if ((metadataToken >> 24) == MemberRefTable.Index && index < MemberRef.RowCount) - { - FieldInfo field = GetMemberRef(index, genericTypeArguments, genericMethodArguments) as FieldInfo; - if (field != null) - { - return field; - } - throw new ArgumentException(String.Format("Token 0x{0:x8} is not a valid FieldInfo token in the scope of module {1}.", metadataToken, this.Name), "metadataToken"); - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - private TypeDefImpl FindFieldOwner(int fieldIndex) - { - // TODO use binary search? - for (int i = 0; i < TypeDef.records.Length; i++) - { - int field = TypeDef.records[i].FieldList - 1; - int end = TypeDef.records.Length > i + 1 ? TypeDef.records[i + 1].FieldList - 1 : Field.records.Length; - if (field <= fieldIndex && fieldIndex < end) - { - PopulateTypeDef(); - return typeDefs[i]; - } - } - throw new InvalidOperationException(); - } - - internal MethodBase GetMethodAt(TypeDefImpl owner, int index) - { - if (methods == null) - { - methods = new MethodBase[MethodDef.records.Length]; - } - if (methods[index] == null) - { - MethodDefImpl method = new MethodDefImpl(this, owner ?? FindMethodOwner(index), index); - methods[index] = method.IsConstructor ? new ConstructorInfoImpl(method) : (MethodBase)method; - } - return methods[index]; - } - - public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if (index < 0) - { - throw TokenOutOfRangeException(metadataToken); - } - else if ((metadataToken >> 24) == MethodDefTable.Index && index < MethodDef.RowCount) - { - return GetMethodAt(null, index); - } - else if ((metadataToken >> 24) == MemberRefTable.Index && index < MemberRef.RowCount) - { - MethodBase method = GetMemberRef(index, genericTypeArguments, genericMethodArguments) as MethodBase; - if (method != null) - { - return method; - } - throw new ArgumentException(String.Format("Token 0x{0:x8} is not a valid MethodBase token in the scope of module {1}.", metadataToken, this.Name), "metadataToken"); - } - else if ((metadataToken >> 24) == MethodSpecTable.Index && index < MethodSpec.RowCount) - { - MethodInfo method = (MethodInfo)ResolveMethod(MethodSpec.records[index].Method, genericTypeArguments, genericMethodArguments); - ByteReader instantiation = ByteReader.FromBlob(blobHeap, MethodSpec.records[index].Instantiation); - return method.MakeGenericMethod(Signature.ReadMethodSpec(this, instantiation, new GenericContext(genericTypeArguments, genericMethodArguments))); - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - public override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if (index < 0) - { - throw TokenOutOfRangeException(metadataToken); - } - else if ((metadataToken >> 24) == MemberRefTable.Index && index < MemberRef.RowCount) - { - int sig = MemberRef.records[index].Signature; - return Signature.ReadOptionalParameterTypes(this, GetBlob(sig), new GenericContext(genericTypeArguments, genericMethodArguments), out customModifiers); - } - else if ((metadataToken >> 24) == MethodDefTable.Index && index < MethodDef.RowCount) - { - // for convenience, we support passing a MethodDef token as well, because in some places - // it makes sense to have a vararg method that is referred to by its methoddef (e.g. ldftn). - // Note that MethodSpec doesn't make sense, because generic methods cannot be vararg. - customModifiers = Empty.Array; - return Type.EmptyTypes; - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - public override string ScopeName - { - get { return GetString(ModuleTable.records[0].Name); } - } - - private TypeDefImpl FindMethodOwner(int methodIndex) - { - // TODO use binary search? - for (int i = 0; i < TypeDef.records.Length; i++) - { - int method = TypeDef.records[i].MethodList - 1; - int end = TypeDef.records.Length > i + 1 ? TypeDef.records[i + 1].MethodList - 1 : MethodDef.records.Length; - if (method <= methodIndex && methodIndex < end) - { - PopulateTypeDef(); - return typeDefs[i]; - } - } - throw new InvalidOperationException(); - } - - private MemberInfo GetMemberRef(int index, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - if (memberRefs == null) - { - memberRefs = new MemberInfo[MemberRef.records.Length]; - } - if (memberRefs[index] == null) - { - int owner = MemberRef.records[index].Class; - int sig = MemberRef.records[index].Signature; - string name = GetString(MemberRef.records[index].Name); - switch (owner >> 24) - { - case MethodDefTable.Index: - return GetMethodAt(null, (owner & 0xFFFFFF) - 1); - case ModuleRefTable.Index: - memberRefs[index] = ResolveTypeMemberRef(ResolveModuleType(owner), name, ByteReader.FromBlob(blobHeap, sig)); - break; - case TypeDefTable.Index: - case TypeRefTable.Index: - memberRefs[index] = ResolveTypeMemberRef(ResolveType(owner), name, ByteReader.FromBlob(blobHeap, sig)); - break; - case TypeSpecTable.Index: - { - Type type = ResolveType(owner, genericTypeArguments, genericMethodArguments); - if (type.IsArray) - { - MethodSignature methodSig = MethodSignature.ReadSig(this, ByteReader.FromBlob(blobHeap, sig), new GenericContext(genericTypeArguments, genericMethodArguments)); - return type.FindMethod(name, methodSig) - ?? universe.GetMissingMethodOrThrow(type, name, methodSig); - } - else if (type.IsConstructedGenericType) - { - MemberInfo member = ResolveTypeMemberRef(type.GetGenericTypeDefinition(), name, ByteReader.FromBlob(blobHeap, sig)); - MethodBase mb = member as MethodBase; - if (mb != null) - { - member = mb.BindTypeParameters(type); - } - FieldInfo fi = member as FieldInfo; - if (fi != null) - { - member = fi.BindTypeParameters(type); - } - return member; - } - else - { - return ResolveTypeMemberRef(type, name, ByteReader.FromBlob(blobHeap, sig)); - } - } - default: - throw new BadImageFormatException(); - } - } - return memberRefs[index]; - } - - private Type ResolveModuleType(int token) - { - int index = (token & 0xFFFFFF) - 1; - string name = GetString(ModuleRef.records[index]); - Module module = assembly.GetModule(name); - if (module == null || module.IsResource()) - { - throw new BadImageFormatException(); - } - return module.GetModuleType(); - } - - private MemberInfo ResolveTypeMemberRef(Type type, string name, ByteReader sig) - { - if (sig.PeekByte() == Signature.FIELD) - { - Type org = type; - FieldSignature fieldSig = FieldSignature.ReadSig(this, sig, type); - FieldInfo field = type.FindField(name, fieldSig); - if (field == null && universe.MissingMemberResolution) - { - return universe.GetMissingFieldOrThrow(type, name, fieldSig); - } - while (field == null && (type = type.BaseType) != null) - { - field = type.FindField(name, fieldSig); - } - if (field != null) - { - return field; - } - throw new MissingFieldException(org.ToString(), name); - } - else - { - Type org = type; - MethodSignature methodSig = MethodSignature.ReadSig(this, sig, type); - MethodBase method = type.FindMethod(name, methodSig); - if (method == null && universe.MissingMemberResolution) - { - return universe.GetMissingMethodOrThrow(type, name, methodSig); - } - while (method == null && (type = type.BaseType) != null) - { - method = type.FindMethod(name, methodSig); - } - if (method != null) - { - return method; - } - throw new MissingMethodException(org.ToString(), name); - } - } - - internal ByteReader GetStandAloneSig(int index) - { - return ByteReader.FromBlob(blobHeap, StandAloneSig.records[index]); - } - - public override byte[] ResolveSignature(int metadataToken) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if ((metadataToken >> 24) == StandAloneSigTable.Index && index >= 0 && index < StandAloneSig.RowCount) - { - ByteReader br = GetStandAloneSig(index); - return br.ReadBytes(br.Length); - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - public override __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - { - int index = (metadataToken & 0xFFFFFF) - 1; - if ((metadataToken >> 24) == StandAloneSigTable.Index && index >= 0 && index < StandAloneSig.RowCount) - { - return MethodSignature.ReadStandAloneMethodSig(this, GetStandAloneSig(index), new GenericContext(genericTypeArguments, genericMethodArguments)); - } - else - { - throw TokenOutOfRangeException(metadataToken); - } - } - - internal MethodInfo GetEntryPoint() - { - if (cliHeader.EntryPointToken != 0 && (cliHeader.Flags & CliHeader.COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) == 0) - { - return (MethodInfo)ResolveMethod((int)cliHeader.EntryPointToken); - } - return null; - } - - internal string[] GetManifestResourceNames() - { - string[] names = new string[ManifestResource.records.Length]; - for (int i = 0; i < ManifestResource.records.Length; i++) - { - names[i] = GetString(ManifestResource.records[i].Name); - } - return names; - } - - internal ManifestResourceInfo GetManifestResourceInfo(string resourceName) - { - for (int i = 0; i < ManifestResource.records.Length; i++) - { - if (resourceName == GetString(ManifestResource.records[i].Name)) - { - ManifestResourceInfo info = new ManifestResourceInfo(this, i); - Assembly asm = info.ReferencedAssembly; - if (asm != null && !asm.__IsMissing && asm.GetManifestResourceInfo(resourceName) == null) - { - return null; - } - return info; - } - } - return null; - } - - internal Stream GetManifestResourceStream(string resourceName) - { - for (int i = 0; i < ManifestResource.records.Length; i++) - { - if (resourceName == GetString(ManifestResource.records[i].Name)) - { - if (ManifestResource.records[i].Implementation != 0x26000000) - { - ManifestResourceInfo info = new ManifestResourceInfo(this, i); - switch (ManifestResource.records[i].Implementation >> 24) - { - case FileTable.Index: - string fileName = Path.Combine(Path.GetDirectoryName(location), info.FileName); - if (System.IO.File.Exists(fileName)) - { - // note that, like System.Reflection, we return null for zero length files and - // ManifestResource.Offset is ignored - FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete); - if (fs.Length == 0) - { - fs.Close(); - return null; - } - return fs; - } - return null; - case AssemblyRefTable.Index: - Assembly asm = info.ReferencedAssembly; - if (asm.__IsMissing) - { - return null; - } - return asm.GetManifestResourceStream(resourceName); - default: - throw new BadImageFormatException(); - } - } - SeekRVA((int)cliHeader.Resources.VirtualAddress + ManifestResource.records[i].Offset); - BinaryReader br = new BinaryReader(stream); - int length = br.ReadInt32(); - return new MemoryStream(br.ReadBytes(length)); - } - } - return null; - } - - public override AssemblyName[] __GetReferencedAssemblies() - { - List list = new List(); - for (int i = 0; i < AssemblyRef.records.Length; i++) - { - AssemblyName name = new AssemblyName(); - name.Name = GetString(AssemblyRef.records[i].Name); - name.Version = new Version( - AssemblyRef.records[i].MajorVersion, - AssemblyRef.records[i].MinorVersion, - AssemblyRef.records[i].BuildNumber, - AssemblyRef.records[i].RevisionNumber); - if (AssemblyRef.records[i].PublicKeyOrToken != 0) - { - byte[] keyOrToken = GetBlobCopy(AssemblyRef.records[i].PublicKeyOrToken); - const int PublicKey = 0x0001; - if ((AssemblyRef.records[i].Flags & PublicKey) != 0) - { - name.SetPublicKey(keyOrToken); - } - else - { - name.SetPublicKeyToken(keyOrToken); - } - } - else - { - name.SetPublicKeyToken(Empty.Array); - } - if (AssemblyRef.records[i].Culture != 0) - { - name.Culture = GetString(AssemblyRef.records[i].Culture); - } - else - { - name.Culture = ""; - } - if (AssemblyRef.records[i].HashValue != 0) - { - name.hash = GetBlobCopy(AssemblyRef.records[i].HashValue); - } - name.Flags = (AssemblyNameFlags)AssemblyRef.records[i].Flags; - list.Add(name); - } - return list.ToArray(); - } - - public override void __ResolveReferencedAssemblies(Assembly[] assemblies) - { - if (assemblyRefs == null) - { - assemblyRefs = new Assembly[AssemblyRef.RowCount]; - } - for (int i = 0; i < assemblies.Length; i++) - { - if (assemblyRefs[i] == null) - { - assemblyRefs[i] = assemblies[i]; - } - } - } - - public override string[] __GetReferencedModules() - { - string[] arr = new string[this.ModuleRef.RowCount]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = GetString(this.ModuleRef.records[i]); - } - return arr; - } - - public override Type[] __GetReferencedTypes() - { - Type[] arr = new Type[this.TypeRef.RowCount]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = ResolveType((TypeRefTable.Index << 24) + i + 1); - } - return arr; - } - - public override Type[] __GetExportedTypes() - { - Type[] arr = new Type[this.ExportedType.RowCount]; - for (int i = 0; i < arr.Length; i++) - { - arr[i] = ResolveExportedType(i); - } - return arr; - } - - private Type ResolveExportedType(int index) - { - TypeName typeName = GetTypeName(ExportedType.records[index].TypeNamespace, ExportedType.records[index].TypeName); - int implementation = ExportedType.records[index].Implementation; - int token = ExportedType.records[index].TypeDefId; - switch (implementation >> 24) - { - case AssemblyRefTable.Index: - return ResolveAssemblyRef((implementation & 0xFFFFFF) - 1).ResolveType(typeName).SetMetadataTokenForMissing(token); - case ExportedTypeTable.Index: - return ResolveExportedType((implementation & 0xFFFFFF) - 1).ResolveNestedType(typeName).SetMetadataTokenForMissing(token); - default: - throw new NotImplementedException(); - } - } - - internal override Type GetModuleType() - { - PopulateTypeDef(); - return moduleType; - } - - public override string __ImageRuntimeVersion - { - get { return imageRuntimeVersion; } - } - - public override int MDStreamVersion - { - get { return metadataStreamVersion; } - } - - public override void __GetDataDirectoryEntry(int index, out int rva, out int length) - { - peFile.GetDataDirectoryEntry(index, out rva, out length); - } - - public override long __RelativeVirtualAddressToFileOffset(int rva) - { - return peFile.RvaToFileOffset((uint)rva); - } - - public override bool __GetSectionInfo(int rva, out string name, out int characteristics) - { - return peFile.GetSectionInfo(rva, out name, out characteristics); - } - - public override int __ReadDataFromRVA(int rva, byte[] data, int offset, int length) - { - SeekRVA(rva); - int totalBytesRead = 0; - while (length > 0) - { - int read = stream.Read(data, offset, length); - if (read == 0) - { - // C++ assemblies can have fields that have an RVA that lies outside of the file - break; - } - offset += read; - length -= read; - totalBytesRead += read; - } - return totalBytesRead; - } - - public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) - { - peKind = 0; - if ((cliHeader.Flags & CliHeader.COMIMAGE_FLAGS_ILONLY) != 0) - { - peKind |= PortableExecutableKinds.ILOnly; - } - switch (cliHeader.Flags & (CliHeader.COMIMAGE_FLAGS_32BITREQUIRED | CliHeader.COMIMAGE_FLAGS_32BITPREFERRED)) - { - case CliHeader.COMIMAGE_FLAGS_32BITREQUIRED: - peKind |= PortableExecutableKinds.Required32Bit; - break; - case CliHeader.COMIMAGE_FLAGS_32BITREQUIRED | CliHeader.COMIMAGE_FLAGS_32BITPREFERRED: - peKind |= PortableExecutableKinds.Preferred32Bit; - break; - default: - // COMIMAGE_FLAGS_32BITPREFERRED by itself is illegal, so we ignore it - // (not setting any flag is ok) - break; - } - if (peFile.OptionalHeader.Magic == IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC) - { - peKind |= PortableExecutableKinds.PE32Plus; - } - - machine = (ImageFileMachine)peFile.FileHeader.Machine; - } - - public override int __Subsystem - { - get { return peFile.OptionalHeader.Subsystem; } - } - - public override IList __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security) - { - TypeName typeName; - switch ((multiple ? 1 : 0) + (security ? 2 : 0)) - { - case 0: - typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHere"); - break; - case 1: - typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereM"); - break; - case 2: - typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereS"); - break; - case 3: - default: - typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereSM"); - break; - } - List list = new List(); - for (int i = 0; i < CustomAttribute.records.Length; i++) - { - if ((CustomAttribute.records[i].Parent >> 24) == TypeRefTable.Index) - { - int index = (CustomAttribute.records[i].Parent & 0xFFFFFF) - 1; - if (typeName == GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName)) - { - list.Add(new CustomAttributeData(this, i)); - } - } - } - return list; - } - - internal override void Dispose() - { - stream.Close(); - } - - internal override void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule) - { - PopulateTypeDef(); - manifestModule.ExportTypes(typeDefs, fileToken); - } - - protected override long GetImageBaseImpl() - { - return (long)peFile.OptionalHeader.ImageBase; - } - - protected override long GetStackReserveImpl() - { - return (long)peFile.OptionalHeader.SizeOfStackReserve; - } - - protected override int GetFileAlignmentImpl() - { - return (int)peFile.OptionalHeader.FileAlignment; - } - - protected override DllCharacteristics GetDllCharacteristicsImpl() - { - return (DllCharacteristics)peFile.OptionalHeader.DllCharacteristics; - } - - public override int __EntryPointRVA - { - get { return (cliHeader.Flags & CliHeader.COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) != 0 ? (int)cliHeader.EntryPointToken : 0; } - } - - public override int __EntryPointToken - { - get { return (cliHeader.Flags & CliHeader.COMIMAGE_FLAGS_NATIVE_ENTRYPOINT) == 0 ? (int)cliHeader.EntryPointToken : 0; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/PEReader.cs b/mcs/class/IKVM.Reflection/Reader/PEReader.cs deleted file mode 100644 index 50928c88e03..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/PEReader.cs +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright (C) 2009 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using BYTE = System.Byte; -using WORD = System.UInt16; -using DWORD = System.UInt32; -using ULONGLONG = System.UInt64; -using System.IO; - -namespace IKVM.Reflection.Reader -{ - sealed class MSDOS_HEADER - { - internal const WORD MAGIC_MZ = 0x5A4D; - - internal WORD signature; // 'MZ' - // skip 58 bytes - internal DWORD peSignatureOffset; - } - - sealed class IMAGE_NT_HEADERS - { - public const DWORD MAGIC_SIGNATURE = 0x00004550; // "PE\0\0" - - public DWORD Signature; - public IMAGE_FILE_HEADER FileHeader = new IMAGE_FILE_HEADER(); - public IMAGE_OPTIONAL_HEADER OptionalHeader = new IMAGE_OPTIONAL_HEADER(); - - internal void Read(BinaryReader br) - { - Signature = br.ReadUInt32(); - if (Signature != IMAGE_NT_HEADERS.MAGIC_SIGNATURE) - { - throw new BadImageFormatException(); - } - FileHeader.Read(br); - OptionalHeader.Read(br); - } - } - - sealed class IMAGE_FILE_HEADER - { - public const WORD IMAGE_FILE_MACHINE_I386 = 0x014c; - public const WORD IMAGE_FILE_MACHINE_IA64 = 0x0200; - public const WORD IMAGE_FILE_MACHINE_AMD64 = 0x8664; - - public const WORD IMAGE_FILE_32BIT_MACHINE = 0x0100; - public const WORD IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002; - public const WORD IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020; - public const WORD IMAGE_FILE_DLL = 0x2000; - - public WORD Machine; - public WORD NumberOfSections; - public DWORD TimeDateStamp; - public DWORD PointerToSymbolTable; - public DWORD NumberOfSymbols; - public WORD SizeOfOptionalHeader; - public WORD Characteristics; - - internal void Read(BinaryReader br) - { - Machine = br.ReadUInt16(); - NumberOfSections = br.ReadUInt16(); - TimeDateStamp = br.ReadUInt32(); - PointerToSymbolTable = br.ReadUInt32(); - NumberOfSymbols = br.ReadUInt32(); - SizeOfOptionalHeader = br.ReadUInt16(); - Characteristics = br.ReadUInt16(); - } - } - - sealed class IMAGE_OPTIONAL_HEADER - { - public const WORD IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b; - public const WORD IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b; - - public const WORD IMAGE_SUBSYSTEM_WINDOWS_GUI = 2; - public const WORD IMAGE_SUBSYSTEM_WINDOWS_CUI = 3; - - public WORD Magic; - public BYTE MajorLinkerVersion; - public BYTE MinorLinkerVersion; - public DWORD SizeOfCode; - public DWORD SizeOfInitializedData; - public DWORD SizeOfUninitializedData; - public DWORD AddressOfEntryPoint; - public DWORD BaseOfCode; - public DWORD BaseOfData; - public ULONGLONG ImageBase; - public DWORD SectionAlignment; - public DWORD FileAlignment; - public WORD MajorOperatingSystemVersion; - public WORD MinorOperatingSystemVersion; - public WORD MajorImageVersion; - public WORD MinorImageVersion; - public WORD MajorSubsystemVersion; - public WORD MinorSubsystemVersion; - public DWORD Win32VersionValue; - public DWORD SizeOfImage; - public DWORD SizeOfHeaders; - public DWORD CheckSum; - public WORD Subsystem; - public WORD DllCharacteristics; - public ULONGLONG SizeOfStackReserve; - public ULONGLONG SizeOfStackCommit; - public ULONGLONG SizeOfHeapReserve; - public ULONGLONG SizeOfHeapCommit; - public DWORD LoaderFlags; - public DWORD NumberOfRvaAndSizes; - public IMAGE_DATA_DIRECTORY[] DataDirectory; - - internal void Read(BinaryReader br) - { - Magic = br.ReadUInt16(); - if (Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) - { - throw new BadImageFormatException(); - } - MajorLinkerVersion = br.ReadByte(); - MinorLinkerVersion = br.ReadByte(); - SizeOfCode = br.ReadUInt32(); - SizeOfInitializedData = br.ReadUInt32(); - SizeOfUninitializedData = br.ReadUInt32(); - AddressOfEntryPoint = br.ReadUInt32(); - BaseOfCode = br.ReadUInt32(); - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - BaseOfData = br.ReadUInt32(); - ImageBase = br.ReadUInt32(); - } - else - { - ImageBase = br.ReadUInt64(); - } - SectionAlignment = br.ReadUInt32(); - FileAlignment = br.ReadUInt32(); - MajorOperatingSystemVersion = br.ReadUInt16(); - MinorOperatingSystemVersion = br.ReadUInt16(); - MajorImageVersion = br.ReadUInt16(); - MinorImageVersion = br.ReadUInt16(); - MajorSubsystemVersion = br.ReadUInt16(); - MinorSubsystemVersion = br.ReadUInt16(); - Win32VersionValue = br.ReadUInt32(); - SizeOfImage = br.ReadUInt32(); - SizeOfHeaders = br.ReadUInt32(); - CheckSum = br.ReadUInt32(); - Subsystem = br.ReadUInt16(); - DllCharacteristics = br.ReadUInt16(); - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - SizeOfStackReserve = br.ReadUInt32(); - SizeOfStackCommit = br.ReadUInt32(); - SizeOfHeapReserve = br.ReadUInt32(); - SizeOfHeapCommit = br.ReadUInt32(); - } - else - { - SizeOfStackReserve = br.ReadUInt64(); - SizeOfStackCommit = br.ReadUInt64(); - SizeOfHeapReserve = br.ReadUInt64(); - SizeOfHeapCommit = br.ReadUInt64(); - } - LoaderFlags = br.ReadUInt32(); - NumberOfRvaAndSizes = br.ReadUInt32(); - DataDirectory = new IMAGE_DATA_DIRECTORY[NumberOfRvaAndSizes]; - for (uint i = 0; i < NumberOfRvaAndSizes; i++) - { - DataDirectory[i] = new IMAGE_DATA_DIRECTORY(); - DataDirectory[i].Read(br); - } - } - } - - struct IMAGE_DATA_DIRECTORY - { - public DWORD VirtualAddress; - public DWORD Size; - - internal void Read(BinaryReader br) - { - VirtualAddress = br.ReadUInt32(); - Size = br.ReadUInt32(); - } - - internal void Write(IKVM.Reflection.Writer.MetadataWriter mw) - { - mw.Write(VirtualAddress); - mw.Write(Size); - } - } - - class SectionHeader - { - public const DWORD IMAGE_SCN_CNT_CODE = 0x00000020; - public const DWORD IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; - public const DWORD IMAGE_SCN_MEM_DISCARDABLE = 0x02000000; - public const DWORD IMAGE_SCN_MEM_EXECUTE = 0x20000000; - public const DWORD IMAGE_SCN_MEM_READ = 0x40000000; - public const DWORD IMAGE_SCN_MEM_WRITE = 0x80000000; - - public string Name; // 8 byte UTF8 encoded 0-padded - public DWORD VirtualSize; - public DWORD VirtualAddress; - public DWORD SizeOfRawData; - public DWORD PointerToRawData; - public DWORD PointerToRelocations; - public DWORD PointerToLinenumbers; - public WORD NumberOfRelocations; - public WORD NumberOfLinenumbers; - public DWORD Characteristics; - - internal void Read(BinaryReader br) - { - char[] name = new char[8]; - int len = 8; - for (int i = 0; i < 8; i++) - { - byte b = br.ReadByte(); - name[i] = (char)b; - if (b == 0 && len == 8) - { - len = i; - } - } - Name = new String(name, 0, len); - VirtualSize = br.ReadUInt32(); - VirtualAddress = br.ReadUInt32(); - SizeOfRawData = br.ReadUInt32(); - PointerToRawData = br.ReadUInt32(); - PointerToRelocations = br.ReadUInt32(); - PointerToLinenumbers = br.ReadUInt32(); - NumberOfRelocations = br.ReadUInt16(); - NumberOfLinenumbers = br.ReadUInt16(); - Characteristics = br.ReadUInt32(); - } - } - - sealed class PEReader - { - private MSDOS_HEADER msdos = new MSDOS_HEADER(); - private IMAGE_NT_HEADERS headers = new IMAGE_NT_HEADERS(); - private SectionHeader[] sections; - - internal void Read(BinaryReader br) - { - msdos.signature = br.ReadUInt16(); - br.BaseStream.Seek(58, SeekOrigin.Current); - msdos.peSignatureOffset = br.ReadUInt32(); - - if (msdos.signature != MSDOS_HEADER.MAGIC_MZ) - { - throw new BadImageFormatException(); - } - - br.BaseStream.Seek(msdos.peSignatureOffset, SeekOrigin.Begin); - headers.Read(br); - sections = new SectionHeader[headers.FileHeader.NumberOfSections]; - for (int i = 0; i < sections.Length; i++) - { - sections[i] = new SectionHeader(); - sections[i].Read(br); - } - } - - internal IMAGE_FILE_HEADER FileHeader - { - get { return headers.FileHeader; } - } - - internal IMAGE_OPTIONAL_HEADER OptionalHeader - { - get { return headers.OptionalHeader; } - } - - internal DWORD GetComDescriptorVirtualAddress() - { - return headers.OptionalHeader.DataDirectory[14].VirtualAddress; - } - - internal void GetDataDirectoryEntry(int index, out int rva, out int length) - { - rva = (int)headers.OptionalHeader.DataDirectory[index].VirtualAddress; - length = (int)headers.OptionalHeader.DataDirectory[index].Size; - } - - internal long RvaToFileOffset(DWORD rva) - { - for (int i = 0; i < sections.Length; i++) - { - if (rva >= sections[i].VirtualAddress && rva < sections[i].VirtualAddress + sections[i].VirtualSize) - { - return sections[i].PointerToRawData + rva - sections[i].VirtualAddress; - } - } - throw new BadImageFormatException(); - } - - internal bool GetSectionInfo(int rva, out string name, out int characteristics) - { - for (int i = 0; i < sections.Length; i++) - { - if (rva >= sections[i].VirtualAddress && rva < sections[i].VirtualAddress + sections[i].VirtualSize) - { - name = sections[i].Name; - characteristics = (int)sections[i].Characteristics; - return true; - } - } - name = null; - characteristics = 0; - return false; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/PropertyInfoImpl.cs b/mcs/class/IKVM.Reflection/Reader/PropertyInfoImpl.cs deleted file mode 100644 index 120b839c5fa..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/PropertyInfoImpl.cs +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class PropertyInfoImpl : PropertyInfo - { - private readonly ModuleReader module; - private readonly Type declaringType; - private readonly int index; - private PropertySignature sig; - private bool isPublic; - private bool isNonPrivate; - private bool isStatic; - private bool flagsCached; - - internal PropertyInfoImpl(ModuleReader module, Type declaringType, int index) - { - this.module = module; - this.declaringType = declaringType; - this.index = index; - } - - public override bool Equals(object obj) - { - PropertyInfoImpl other = obj as PropertyInfoImpl; - return other != null && other.DeclaringType == declaringType && other.index == index; - } - - public override int GetHashCode() - { - return declaringType.GetHashCode() * 77 + index; - } - - internal override PropertySignature PropertySignature - { - get - { - if (sig == null) - { - sig = PropertySignature.ReadSig(module, module.GetBlob(module.Property.records[index].Type), declaringType); - } - return sig; - } - } - - public override PropertyAttributes Attributes - { - get { return (PropertyAttributes)module.Property.records[index].Flags; } - } - - public override object GetRawConstantValue() - { - return module.Constant.GetRawConstantValue(module, this.MetadataToken); - } - - public override bool CanRead - { - get { return GetGetMethod(true) != null; } - } - - public override bool CanWrite - { - get { return GetSetMethod(true) != null; } - } - - public override MethodInfo GetGetMethod(bool nonPublic) - { - return module.MethodSemantics.GetMethod(module, this.MetadataToken, nonPublic, MethodSemanticsTable.Getter); - } - - public override MethodInfo GetSetMethod(bool nonPublic) - { - return module.MethodSemantics.GetMethod(module, this.MetadataToken, nonPublic, MethodSemanticsTable.Setter); - } - - public override MethodInfo[] GetAccessors(bool nonPublic) - { - return module.MethodSemantics.GetMethods(module, this.MetadataToken, nonPublic, MethodSemanticsTable.Getter | MethodSemanticsTable.Setter | MethodSemanticsTable.Other); - } - - public override Type DeclaringType - { - get { return declaringType; } - } - - public override Module Module - { - get { return module; } - } - - public override int MetadataToken - { - get { return (PropertyTable.Index << 24) + index + 1; } - } - - public override string Name - { - get { return module.GetString(module.Property.records[index].Name); } - } - - internal override bool IsPublic - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isPublic; - } - } - - internal override bool IsNonPrivate - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isNonPrivate; - } - } - - internal override bool IsStatic - { - get - { - if (!flagsCached) - { - ComputeFlags(); - } - return isStatic; - } - } - - private void ComputeFlags() - { - module.MethodSemantics.ComputeFlags(module, this.MetadataToken, out isPublic, out isNonPrivate, out isStatic); - flagsCached = true; - } - - internal override bool IsBaked - { - get { return true; } - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/ResourceModule.cs b/mcs/class/IKVM.Reflection/Reader/ResourceModule.cs deleted file mode 100644 index 0113e470642..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/ResourceModule.cs +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class ResourceModule : NonPEModule - { - private readonly ModuleReader manifest; - private readonly int index; - private readonly string location; - - internal ResourceModule(ModuleReader manifest, int index, string location) - : base(manifest.universe) - { - this.manifest = manifest; - this.index = index; - this.location = location; - } - - public override int MDStreamVersion - { - get { throw new NotSupportedException(); } - } - - public override bool IsResource() - { - return true; - } - - public override Assembly Assembly - { - get { return manifest.Assembly; } - } - - public override string FullyQualifiedName - { - get { return location ?? ""; } - } - - public override string Name - { - get { return location == null ? "" : System.IO.Path.GetFileName(location); } - } - - public override string ScopeName - { - get { return manifest.GetString(manifest.File.records[index].Name); } - } - - public override Guid ModuleVersionId - { - get { throw new NotSupportedException(); } - } - - public override byte[] __ModuleHash - { - get - { - int blob = manifest.File.records[index].HashValue; - return blob == 0 ? Empty.Array : manifest.GetBlobCopy(blob); - } - } - - internal override Type FindType(TypeName typeName) - { - return null; - } - - internal override Type FindTypeIgnoreCase(TypeName lowerCaseName) - { - return null; - } - - internal override void GetTypesImpl(List list) - { - } - - protected override Exception ArgumentOutOfRangeException() - { - return new NotSupportedException(); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Reader/TypeDefImpl.cs b/mcs/class/IKVM.Reflection/Reader/TypeDefImpl.cs deleted file mode 100644 index e4a036d5674..00000000000 --- a/mcs/class/IKVM.Reflection/Reader/TypeDefImpl.cs +++ /dev/null @@ -1,425 +0,0 @@ -/* - Copyright (C) 2009-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Reader -{ - sealed class TypeDefImpl : TypeInfo - { - private readonly ModuleReader module; - private readonly int index; - private readonly string typeName; - private readonly string typeNamespace; - private Type[] typeArgs; - - internal TypeDefImpl(ModuleReader module, int index) - { - this.module = module; - this.index = index; - this.typeName = module.GetString(module.TypeDef.records[index].TypeName); - this.typeNamespace = module.GetString(module.TypeDef.records[index].TypeNamespace); - MarkEnumOrValueType(typeNamespace, typeName); - } - - public override Type BaseType - { - get - { - int extends = module.TypeDef.records[index].Extends; - if ((extends & 0xFFFFFF) == 0) - { - return null; - } - return module.ResolveType(extends, this); - } - } - - public override TypeAttributes Attributes - { - get { return (TypeAttributes)module.TypeDef.records[index].Flags; } - } - - public override EventInfo[] __GetDeclaredEvents() - { - foreach (int i in module.EventMap.Filter(this.MetadataToken)) - { - int evt = module.EventMap.records[i].EventList - 1; - int end = module.EventMap.records.Length > i + 1 ? module.EventMap.records[i + 1].EventList - 1 : module.Event.records.Length; - EventInfo[] events = new EventInfo[end - evt]; - if (module.EventPtr.RowCount == 0) - { - for (int j = 0; evt < end; evt++, j++) - { - events[j] = new EventInfoImpl(module, this, evt); - } - } - else - { - for (int j = 0; evt < end; evt++, j++) - { - events[j] = new EventInfoImpl(module, this, module.EventPtr.records[evt] - 1); - } - } - return events; - } - return Empty.Array; - } - - public override FieldInfo[] __GetDeclaredFields() - { - int field = module.TypeDef.records[index].FieldList - 1; - int end = module.TypeDef.records.Length > index + 1 ? module.TypeDef.records[index + 1].FieldList - 1 : module.Field.records.Length; - FieldInfo[] fields = new FieldInfo[end - field]; - if (module.FieldPtr.RowCount == 0) - { - for (int i = 0; field < end; i++, field++) - { - fields[i] = module.GetFieldAt(this, field); - } - } - else - { - for (int i = 0; field < end; i++, field++) - { - fields[i] = module.GetFieldAt(this, module.FieldPtr.records[field] - 1); - } - } - return fields; - } - - public override Type[] __GetDeclaredInterfaces() - { - List list = null; - foreach (int i in module.InterfaceImpl.Filter(this.MetadataToken)) - { - if (list == null) - { - list = new List(); - } - list.Add(module.ResolveType(module.InterfaceImpl.records[i].Interface, this)); - } - return Util.ToArray(list, Type.EmptyTypes); - } - - public override MethodBase[] __GetDeclaredMethods() - { - int method = module.TypeDef.records[index].MethodList - 1; - int end = module.TypeDef.records.Length > index + 1 ? module.TypeDef.records[index + 1].MethodList - 1 : module.MethodDef.records.Length; - MethodBase[] methods = new MethodBase[end - method]; - if (module.MethodPtr.RowCount == 0) - { - for (int i = 0; method < end; method++, i++) - { - methods[i] = module.GetMethodAt(this, method); - } - } - else - { - for (int i = 0; method < end; method++, i++) - { - methods[i] = module.GetMethodAt(this, module.MethodPtr.records[method] - 1); - } - } - return methods; - } - - public override __MethodImplMap __GetMethodImplMap() - { - PopulateGenericArguments(); - List bodies = new List(); - List> declarations = new List>(); - foreach (int i in module.MethodImpl.Filter(this.MetadataToken)) - { - MethodInfo body = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodBody, typeArgs, null); - int index = bodies.IndexOf(body); - if (index == -1) - { - index = bodies.Count; - bodies.Add(body); - declarations.Add(new List()); - } - MethodInfo declaration = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null); - declarations[index].Add(declaration); - } - __MethodImplMap map = new __MethodImplMap(); - map.TargetType = this; - map.MethodBodies = bodies.ToArray(); - map.MethodDeclarations = new MethodInfo[declarations.Count][]; - for (int i = 0; i < map.MethodDeclarations.Length; i++) - { - map.MethodDeclarations[i] = declarations[i].ToArray(); - } - return map; - } - - public override Type[] __GetDeclaredTypes() - { - int token = this.MetadataToken; - List list = new List(); - // note that the NestedClass table is sorted on NestedClass, so we can't use binary search - for (int i = 0; i < module.NestedClass.records.Length; i++) - { - if (module.NestedClass.records[i].EnclosingClass == token) - { - list.Add(module.ResolveType(module.NestedClass.records[i].NestedClass)); - } - } - return list.ToArray(); - } - - public override PropertyInfo[] __GetDeclaredProperties() - { - foreach (int i in module.PropertyMap.Filter(this.MetadataToken)) - { - int property = module.PropertyMap.records[i].PropertyList - 1; - int end = module.PropertyMap.records.Length > i + 1 ? module.PropertyMap.records[i + 1].PropertyList - 1 : module.Property.records.Length; - PropertyInfo[] properties = new PropertyInfo[end - property]; - if (module.PropertyPtr.RowCount == 0) - { - for (int j = 0; property < end; property++, j++) - { - properties[j] = new PropertyInfoImpl(module, this, property); - } - } - else - { - for (int j = 0; property < end; property++, j++) - { - properties[j] = new PropertyInfoImpl(module, this, module.PropertyPtr.records[property] - 1); - } - } - return properties; - } - return Empty.Array; - } - - public override string __Name - { - get { return typeName; } - } - - public override string __Namespace - { - get { return typeNamespace; } - } - - public override string Name - { - get { return TypeNameParser.Escape(typeName); } - } - - public override string FullName - { - get { return GetFullName(); } - } - - public override int MetadataToken - { - get { return (TypeDefTable.Index << 24) + index + 1; } - } - - public override Type[] GetGenericArguments() - { - PopulateGenericArguments(); - return Util.Copy(typeArgs); - } - - private void PopulateGenericArguments() - { - if (typeArgs == null) - { - int token = this.MetadataToken; - int first = module.GenericParam.FindFirstByOwner(token); - if (first == -1) - { - typeArgs = Type.EmptyTypes; - } - else - { - List list = new List(); - int len = module.GenericParam.records.Length; - for (int i = first; i < len && module.GenericParam.records[i].Owner == token; i++) - { - list.Add(new GenericTypeParameter(module, i)); - } - typeArgs = list.ToArray(); - } - } - } - - internal override Type GetGenericTypeArgument(int index) - { - PopulateGenericArguments(); - return typeArgs[index]; - } - - public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - PopulateGenericArguments(); - return new CustomModifiers[typeArgs.Length]; - } - - public override bool IsGenericType - { - get { return IsGenericTypeDefinition; } - } - - public override bool IsGenericTypeDefinition - { - get - { - if ((typeFlags & (TypeFlags.IsGenericTypeDefinition | TypeFlags.NotGenericTypeDefinition)) == 0) - { - typeFlags |= module.GenericParam.FindFirstByOwner(this.MetadataToken) == -1 - ? TypeFlags.NotGenericTypeDefinition - : TypeFlags.IsGenericTypeDefinition; - } - return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; - } - } - - public override Type GetGenericTypeDefinition() - { - if (IsGenericTypeDefinition) - { - return this; - } - throw new InvalidOperationException(); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(this.FullName); - string sep = "["; - foreach (Type arg in GetGenericArguments()) - { - sb.Append(sep); - sb.Append(arg); - sep = ","; - } - if (sep != "[") - { - sb.Append(']'); - } - return sb.ToString(); - } - - internal bool IsNestedByFlags - { - get { return (this.Attributes & TypeAttributes.VisibilityMask & ~TypeAttributes.Public) != 0; } - } - - public override Type DeclaringType - { - get - { - // note that we cannot use Type.IsNested for this, because that calls DeclaringType - if (!IsNestedByFlags) - { - return null; - } - foreach (int i in module.NestedClass.Filter(this.MetadataToken)) - { - return module.ResolveType(module.NestedClass.records[i].EnclosingClass, null, null); - } - throw new InvalidOperationException(); - } - } - - public override StructLayoutAttribute StructLayoutAttribute - { - get - { - StructLayoutAttribute layout; - switch (this.Attributes & TypeAttributes.LayoutMask) - { - case TypeAttributes.AutoLayout: - layout = new StructLayoutAttribute(LayoutKind.Auto); - break; - case TypeAttributes.SequentialLayout: - layout = new StructLayoutAttribute(LayoutKind.Sequential); - break; - case TypeAttributes.ExplicitLayout: - layout = new StructLayoutAttribute(LayoutKind.Explicit); - break; - default: - throw new BadImageFormatException(); - } - switch (this.Attributes & TypeAttributes.StringFormatMask) - { - case TypeAttributes.AnsiClass: - layout.CharSet = CharSet.Ansi; - break; - case TypeAttributes.UnicodeClass: - layout.CharSet = CharSet.Unicode; - break; - case TypeAttributes.AutoClass: - layout.CharSet = CharSet.Auto; - break; - default: - layout.CharSet = CharSet.None; - break; - } - if (!__GetLayout(out layout.Pack, out layout.Size)) - { - // compatibility with System.Reflection - layout.Pack = 8; - } - return layout; - } - } - - public override bool __GetLayout(out int packingSize, out int typeSize) - { - foreach (int i in module.ClassLayout.Filter(this.MetadataToken)) - { - packingSize = module.ClassLayout.records[i].PackingSize; - typeSize = module.ClassLayout.records[i].ClassSize; - return true; - } - packingSize = 0; - typeSize = 0; - return false; - } - - public override Module Module - { - get { return module; } - } - - internal override bool IsModulePseudoType - { - get { return index == 0; } - } - - internal override bool IsBaked - { - get { return true; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Signature.cs b/mcs/class/IKVM.Reflection/Signature.cs deleted file mode 100644 index 68c3f10fd28..00000000000 --- a/mcs/class/IKVM.Reflection/Signature.cs +++ /dev/null @@ -1,681 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; -using CallingConvention = System.Runtime.InteropServices.CallingConvention; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Writer; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection -{ - abstract class Signature - { - internal const byte DEFAULT = 0x00; - internal const byte VARARG = 0x05; - internal const byte GENERIC = 0x10; - internal const byte HASTHIS = 0x20; - internal const byte EXPLICITTHIS = 0x40; - internal const byte FIELD = 0x06; - internal const byte LOCAL_SIG = 0x07; - internal const byte PROPERTY = 0x08; - internal const byte GENERICINST = 0x0A; - internal const byte SENTINEL = 0x41; - internal const byte ELEMENT_TYPE_VOID = 0x01; - internal const byte ELEMENT_TYPE_BOOLEAN = 0x02; - internal const byte ELEMENT_TYPE_CHAR = 0x03; - internal const byte ELEMENT_TYPE_I1 = 0x04; - internal const byte ELEMENT_TYPE_U1 = 0x05; - internal const byte ELEMENT_TYPE_I2 = 0x06; - internal const byte ELEMENT_TYPE_U2 = 0x07; - internal const byte ELEMENT_TYPE_I4 = 0x08; - internal const byte ELEMENT_TYPE_U4 = 0x09; - internal const byte ELEMENT_TYPE_I8 = 0x0a; - internal const byte ELEMENT_TYPE_U8 = 0x0b; - internal const byte ELEMENT_TYPE_R4 = 0x0c; - internal const byte ELEMENT_TYPE_R8 = 0x0d; - internal const byte ELEMENT_TYPE_STRING = 0x0e; - internal const byte ELEMENT_TYPE_PTR = 0x0f; - internal const byte ELEMENT_TYPE_BYREF = 0x10; - internal const byte ELEMENT_TYPE_VALUETYPE = 0x11; - internal const byte ELEMENT_TYPE_CLASS = 0x12; - internal const byte ELEMENT_TYPE_VAR = 0x13; - internal const byte ELEMENT_TYPE_ARRAY = 0x14; - internal const byte ELEMENT_TYPE_GENERICINST = 0x15; - internal const byte ELEMENT_TYPE_TYPEDBYREF = 0x16; - internal const byte ELEMENT_TYPE_I = 0x18; - internal const byte ELEMENT_TYPE_U = 0x19; - internal const byte ELEMENT_TYPE_FNPTR = 0x1b; - internal const byte ELEMENT_TYPE_OBJECT = 0x1c; - internal const byte ELEMENT_TYPE_SZARRAY = 0x1d; - internal const byte ELEMENT_TYPE_MVAR = 0x1e; - internal const byte ELEMENT_TYPE_CMOD_REQD = 0x1f; - internal const byte ELEMENT_TYPE_CMOD_OPT = 0x20; - internal const byte ELEMENT_TYPE_PINNED = 0x45; - - internal abstract void WriteSig(ModuleBuilder module, ByteBuffer bb); - - private static Type ReadGenericInst(ModuleReader module, ByteReader br, IGenericContext context) - { - Type type; - switch (br.ReadByte()) - { - case ELEMENT_TYPE_CLASS: - type = ReadTypeDefOrRefEncoded(module, br, context).MarkNotValueType(); - break; - case ELEMENT_TYPE_VALUETYPE: - type = ReadTypeDefOrRefEncoded(module, br, context).MarkValueType(); - break; - default: - throw new BadImageFormatException(); - } - if (!type.__IsMissing && !type.IsGenericTypeDefinition) - { - throw new BadImageFormatException(); - } - int genArgCount = br.ReadCompressedInt(); - Type[] args = new Type[genArgCount]; - CustomModifiers[] mods = null; - for (int i = 0; i < genArgCount; i++) - { - // LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for genericinst, but C++ uses it, the verifier allows it and ildasm also supports it - CustomModifiers cm = CustomModifiers.Read(module, br, context); - if (!cm.IsEmpty) - { - if (mods == null) - { - mods = new CustomModifiers[genArgCount]; - } - mods[i] = cm; - } - args[i] = ReadType(module, br, context); - } - return GenericTypeInstance.Make(type, args, mods); - } - - internal static Type ReadTypeSpec(ModuleReader module, ByteReader br, IGenericContext context) - { - // LAMESPEC a TypeSpec can contain custom modifiers (C++/CLI generates "newarr (TypeSpec with custom modifiers)") - CustomModifiers.Skip(br); - // LAMESPEC anything can be adorned by (useless) custom modifiers - // also, VAR and MVAR are also used in TypeSpec (contrary to what the spec says) - return ReadType(module, br, context); - } - - private static Type ReadFunctionPointer(ModuleReader module, ByteReader br, IGenericContext context) - { - __StandAloneMethodSig sig = MethodSignature.ReadStandAloneMethodSig(module, br, context); - if (module.universe.EnableFunctionPointers) - { - return FunctionPointerType.Make(module.universe, sig); - } - else - { - // by default, like .NET we return System.IntPtr here - return module.universe.System_IntPtr; - } - } - - internal static Type[] ReadMethodSpec(ModuleReader module, ByteReader br, IGenericContext context) - { - if (br.ReadByte() != GENERICINST) - { - throw new BadImageFormatException(); - } - Type[] args = new Type[br.ReadCompressedInt()]; - for (int i = 0; i < args.Length; i++) - { - args[i] = ReadType(module, br, context); - } - return args; - } - - private static int[] ReadArrayBounds(ByteReader br) - { - int num = br.ReadCompressedInt(); - if (num == 0) - { - return null; - } - int[] arr = new int[num]; - for (int i = 0; i < num; i++) - { - arr[i] = br.ReadCompressedInt(); - } - return arr; - } - - private static Type ReadTypeOrVoid(ModuleReader module, ByteReader br, IGenericContext context) - { - if (br.PeekByte() == ELEMENT_TYPE_VOID) - { - br.ReadByte(); - return module.universe.System_Void; - } - else - { - return ReadType(module, br, context); - } - } - - // see ECMA 335 CLI spec June 2006 section 23.2.12 for this production - protected static Type ReadType(ModuleReader module, ByteReader br, IGenericContext context) - { - CustomModifiers mods; - switch (br.ReadByte()) - { - case ELEMENT_TYPE_CLASS: - return ReadTypeDefOrRefEncoded(module, br, context).MarkNotValueType(); - case ELEMENT_TYPE_VALUETYPE: - return ReadTypeDefOrRefEncoded(module, br, context).MarkValueType(); - case ELEMENT_TYPE_BOOLEAN: - return module.universe.System_Boolean; - case ELEMENT_TYPE_CHAR: - return module.universe.System_Char; - case ELEMENT_TYPE_I1: - return module.universe.System_SByte; - case ELEMENT_TYPE_U1: - return module.universe.System_Byte; - case ELEMENT_TYPE_I2: - return module.universe.System_Int16; - case ELEMENT_TYPE_U2: - return module.universe.System_UInt16; - case ELEMENT_TYPE_I4: - return module.universe.System_Int32; - case ELEMENT_TYPE_U4: - return module.universe.System_UInt32; - case ELEMENT_TYPE_I8: - return module.universe.System_Int64; - case ELEMENT_TYPE_U8: - return module.universe.System_UInt64; - case ELEMENT_TYPE_R4: - return module.universe.System_Single; - case ELEMENT_TYPE_R8: - return module.universe.System_Double; - case ELEMENT_TYPE_I: - return module.universe.System_IntPtr; - case ELEMENT_TYPE_U: - return module.universe.System_UIntPtr; - case ELEMENT_TYPE_STRING: - return module.universe.System_String; - case ELEMENT_TYPE_OBJECT: - return module.universe.System_Object; - case ELEMENT_TYPE_VAR: - return context.GetGenericTypeArgument(br.ReadCompressedInt()); - case ELEMENT_TYPE_MVAR: - return context.GetGenericMethodArgument(br.ReadCompressedInt()); - case ELEMENT_TYPE_GENERICINST: - return ReadGenericInst(module, br, context); - case ELEMENT_TYPE_SZARRAY: - mods = CustomModifiers.Read(module, br, context); - return ReadType(module, br, context).__MakeArrayType(mods); - case ELEMENT_TYPE_ARRAY: - mods = CustomModifiers.Read(module, br, context); - return ReadType(module, br, context).__MakeArrayType(br.ReadCompressedInt(), ReadArrayBounds(br), ReadArrayBounds(br), mods); - case ELEMENT_TYPE_PTR: - mods = CustomModifiers.Read(module, br, context); - return ReadTypeOrVoid(module, br, context).__MakePointerType(mods); - case ELEMENT_TYPE_FNPTR: - return ReadFunctionPointer(module, br, context); - default: - throw new BadImageFormatException(); - } - } - - internal static void ReadLocalVarSig(ModuleReader module, ByteReader br, IGenericContext context, List list) - { - if (br.Length < 2 || br.ReadByte() != LOCAL_SIG) - { - throw new BadImageFormatException("Invalid local variable signature"); - } - int count = br.ReadCompressedInt(); - for (int i = 0; i < count; i++) - { - if (br.PeekByte() == ELEMENT_TYPE_TYPEDBYREF) - { - br.ReadByte(); - list.Add(new LocalVariableInfo(i, module.universe.System_TypedReference, false, new CustomModifiers())); - } - else - { - CustomModifiers mods1 = CustomModifiers.Read(module, br, context); - bool pinned = false; - if (br.PeekByte() == ELEMENT_TYPE_PINNED) - { - br.ReadByte(); - pinned = true; - } - CustomModifiers mods2 = CustomModifiers.Read(module, br, context); - Type type = ReadTypeOrByRef(module, br, context); - list.Add(new LocalVariableInfo(i, type, pinned, CustomModifiers.Combine(mods1, mods2))); - } - } - } - - private static Type ReadTypeOrByRef(ModuleReader module, ByteReader br, IGenericContext context) - { - if (br.PeekByte() == ELEMENT_TYPE_BYREF) - { - br.ReadByte(); - // LAMESPEC it is allowed (by C++/CLI, ilasm and peverify) to have custom modifiers after the BYREF - // (which makes sense, as it is analogous to pointers) - CustomModifiers mods = CustomModifiers.Read(module, br, context); - // C++/CLI generates void& local variables, so we need to use ReadTypeOrVoid here - return ReadTypeOrVoid(module, br, context).__MakeByRefType(mods); - } - else - { - return ReadType(module, br, context); - } - } - - protected static Type ReadRetType(ModuleReader module, ByteReader br, IGenericContext context) - { - switch (br.PeekByte()) - { - case ELEMENT_TYPE_VOID: - br.ReadByte(); - return module.universe.System_Void; - case ELEMENT_TYPE_TYPEDBYREF: - br.ReadByte(); - return module.universe.System_TypedReference; - default: - return ReadTypeOrByRef(module, br, context); - } - } - - protected static Type ReadParam(ModuleReader module, ByteReader br, IGenericContext context) - { - switch (br.PeekByte()) - { - case ELEMENT_TYPE_TYPEDBYREF: - br.ReadByte(); - return module.universe.System_TypedReference; - default: - return ReadTypeOrByRef(module, br, context); - } - } - - protected static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type) - { - while (type.HasElementType) - { - if (type.__IsVector) - { - bb.Write(ELEMENT_TYPE_SZARRAY); - } - else if (type.IsArray) - { - int rank = type.GetArrayRank(); - bb.Write(ELEMENT_TYPE_ARRAY); - // LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for arrays, but the verifier allows it and ildasm also supports it - WriteCustomModifiers(module, bb, type.__GetCustomModifiers()); - WriteType(module, bb, type.GetElementType()); - bb.WriteCompressedInt(rank); - int[] sizes = type.__GetArraySizes(); - bb.WriteCompressedInt(sizes.Length); - for (int i = 0; i < sizes.Length; i++) - { - bb.WriteCompressedInt(sizes[i]); - } - int[] lobounds = type.__GetArrayLowerBounds(); - bb.WriteCompressedInt(lobounds.Length); - for (int i = 0; i < lobounds.Length; i++) - { - bb.WriteCompressedInt(lobounds[i]); - } - return; - } - else if (type.IsByRef) - { - bb.Write(ELEMENT_TYPE_BYREF); - } - else if (type.IsPointer) - { - bb.Write(ELEMENT_TYPE_PTR); - } - WriteCustomModifiers(module, bb, type.__GetCustomModifiers()); - type = type.GetElementType(); - } - Universe u = module.universe; - if (type == u.System_Void) - { - bb.Write(ELEMENT_TYPE_VOID); - } - else if (type == u.System_Int32) - { - bb.Write(ELEMENT_TYPE_I4); - } - else if (type == u.System_Boolean) - { - bb.Write(ELEMENT_TYPE_BOOLEAN); - } - else if (type == u.System_String) - { - bb.Write(ELEMENT_TYPE_STRING); - } - else if (type == u.System_Char) - { - bb.Write(ELEMENT_TYPE_CHAR); - } - else if (type == u.System_SByte) - { - bb.Write(ELEMENT_TYPE_I1); - } - else if (type == u.System_Byte) - { - bb.Write(ELEMENT_TYPE_U1); - } - else if (type == u.System_Int16) - { - bb.Write(ELEMENT_TYPE_I2); - } - else if (type == u.System_UInt16) - { - bb.Write(ELEMENT_TYPE_U2); - } - else if (type == u.System_UInt32) - { - bb.Write(ELEMENT_TYPE_U4); - } - else if (type == u.System_Int64) - { - bb.Write(ELEMENT_TYPE_I8); - } - else if (type == u.System_UInt64) - { - bb.Write(ELEMENT_TYPE_U8); - } - else if (type == u.System_Single) - { - bb.Write(ELEMENT_TYPE_R4); - } - else if (type == u.System_Double) - { - bb.Write(ELEMENT_TYPE_R8); - } - else if (type == u.System_IntPtr) - { - bb.Write(ELEMENT_TYPE_I); - } - else if (type == u.System_UIntPtr) - { - bb.Write(ELEMENT_TYPE_U); - } - else if (type == u.System_TypedReference) - { - bb.Write(ELEMENT_TYPE_TYPEDBYREF); - } - else if (type == u.System_Object) - { - bb.Write(ELEMENT_TYPE_OBJECT); - } - else if (type.IsGenericParameter) - { - if (type is UnboundGenericMethodParameter || type.DeclaringMethod != null) - { - bb.Write(ELEMENT_TYPE_MVAR); - } - else - { - bb.Write(ELEMENT_TYPE_VAR); - } - bb.WriteCompressedInt(type.GenericParameterPosition); - } - else if (!type.__IsMissing && type.IsGenericType) - { - WriteGenericSignature(module, bb, type); - } - else if (type.__IsFunctionPointer) - { - bb.Write(ELEMENT_TYPE_FNPTR); - WriteStandAloneMethodSig(module, bb, type.__MethodSignature); - } - else - { - if (type.IsValueType) - { - bb.Write(ELEMENT_TYPE_VALUETYPE); - } - else - { - bb.Write(ELEMENT_TYPE_CLASS); - } - bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token); - } - } - - private static void WriteGenericSignature(ModuleBuilder module, ByteBuffer bb, Type type) - { - Type[] typeArguments = type.GetGenericArguments(); - CustomModifiers[] customModifiers = type.__GetGenericArgumentsCustomModifiers(); - if (!type.IsGenericTypeDefinition) - { - type = type.GetGenericTypeDefinition(); - } - bb.Write(ELEMENT_TYPE_GENERICINST); - if (type.IsValueType) - { - bb.Write(ELEMENT_TYPE_VALUETYPE); - } - else - { - bb.Write(ELEMENT_TYPE_CLASS); - } - bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token); - bb.WriteCompressedInt(typeArguments.Length); - for (int i = 0; i < typeArguments.Length; i++) - { - WriteCustomModifiers(module, bb, customModifiers[i]); - WriteType(module, bb, typeArguments[i]); - } - } - - protected static void WriteCustomModifiers(ModuleBuilder module, ByteBuffer bb, CustomModifiers modifiers) - { - foreach (CustomModifiers.Entry entry in modifiers) - { - bb.Write(entry.IsRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT); - bb.WriteTypeDefOrRefEncoded(module.GetTypeTokenForMemberRef(entry.Type)); - } - } - - internal static Type ReadTypeDefOrRefEncoded(ModuleReader module, ByteReader br, IGenericContext context) - { - int encoded = br.ReadCompressedInt(); - switch (encoded & 3) - { - case 0: - return module.ResolveType((TypeDefTable.Index << 24) + (encoded >> 2), null, null); - case 1: - return module.ResolveType((TypeRefTable.Index << 24) + (encoded >> 2), null, null); - case 2: - return module.ResolveType((TypeSpecTable.Index << 24) + (encoded >> 2), context); - default: - throw new BadImageFormatException(); - } - } - - internal static void WriteStandAloneMethodSig(ModuleBuilder module, ByteBuffer bb, __StandAloneMethodSig sig) - { - if (sig.IsUnmanaged) - { - switch (sig.UnmanagedCallingConvention) - { - case CallingConvention.Cdecl: - bb.Write((byte)0x01); // C - break; - case CallingConvention.StdCall: - case CallingConvention.Winapi: - bb.Write((byte)0x02); // STDCALL - break; - case CallingConvention.ThisCall: - bb.Write((byte)0x03); // THISCALL - break; - case CallingConvention.FastCall: - bb.Write((byte)0x04); // FASTCALL - break; - default: - throw new ArgumentOutOfRangeException("callingConvention"); - } - } - else - { - CallingConventions callingConvention = sig.CallingConvention; - byte flags = 0; - if ((callingConvention & CallingConventions.HasThis) != 0) - { - flags |= HASTHIS; - } - if ((callingConvention & CallingConventions.ExplicitThis) != 0) - { - flags |= EXPLICITTHIS; - } - if ((callingConvention & CallingConventions.VarArgs) != 0) - { - flags |= VARARG; - } - bb.Write(flags); - } - Type[] parameterTypes = sig.ParameterTypes; - Type[] optionalParameterTypes = sig.OptionalParameterTypes; - bb.WriteCompressedInt(parameterTypes.Length + optionalParameterTypes.Length); - WriteCustomModifiers(module, bb, sig.GetReturnTypeCustomModifiers()); - WriteType(module, bb, sig.ReturnType); - int index = 0; - foreach (Type t in parameterTypes) - { - WriteCustomModifiers(module, bb, sig.GetParameterCustomModifiers(index++)); - WriteType(module, bb, t); - } - // note that optional parameters are only allowed for managed signatures (but we don't enforce that) - if (optionalParameterTypes.Length > 0) - { - bb.Write(SENTINEL); - foreach (Type t in optionalParameterTypes) - { - WriteCustomModifiers(module, bb, sig.GetParameterCustomModifiers(index++)); - WriteType(module, bb, t); - } - } - } - - internal static void WriteTypeSpec(ModuleBuilder module, ByteBuffer bb, Type type) - { - WriteType(module, bb, type); - } - - internal static void WriteMethodSpec(ModuleBuilder module, ByteBuffer bb, Type[] genArgs) - { - bb.Write(GENERICINST); - bb.WriteCompressedInt(genArgs.Length); - foreach (Type arg in genArgs) - { - WriteType(module, bb, arg); - } - } - - // this reads just the optional parameter types, from a MethodRefSig - internal static Type[] ReadOptionalParameterTypes(ModuleReader module, ByteReader br, IGenericContext context, out CustomModifiers[] customModifiers) - { - br.ReadByte(); - int paramCount = br.ReadCompressedInt(); - CustomModifiers.Skip(br); - ReadRetType(module, br, context); - for (int i = 0; i < paramCount; i++) - { - if (br.PeekByte() == SENTINEL) - { - br.ReadByte(); - Type[] types = new Type[paramCount - i]; - customModifiers = new CustomModifiers[types.Length]; - for (int j = 0; j < types.Length; j++) - { - customModifiers[j] = CustomModifiers.Read(module, br, context); - types[j] = ReadType(module, br, context); - } - return types; - } - CustomModifiers.Skip(br); - ReadType(module, br, context); - } - customModifiers = Empty.Array; - return Type.EmptyTypes; - } - - protected static Type[] BindTypeParameters(IGenericBinder binder, Type[] types) - { - if (types == null || types.Length == 0) - { - return Type.EmptyTypes; - } - Type[] expanded = new Type[types.Length]; - for (int i = 0; i < types.Length; i++) - { - expanded[i] = types[i].BindTypeParameters(binder); - } - return expanded; - } - - internal static void WriteSignatureHelper(ModuleBuilder module, ByteBuffer bb, byte flags, ushort paramCount, List args) - { - bb.Write(flags); - if (flags != FIELD) - { - bb.WriteCompressedInt(paramCount); - } - foreach (Type type in args) - { - if (type == MarkerType.ModOpt) - { - bb.Write(ELEMENT_TYPE_CMOD_OPT); - } - else if (type == MarkerType.ModReq) - { - bb.Write(ELEMENT_TYPE_CMOD_REQD); - } - else if (type == MarkerType.Sentinel) - { - bb.Write(SENTINEL); - } - else if (type == MarkerType.Pinned) - { - bb.Write(ELEMENT_TYPE_PINNED); - } - else if (type == null) - { - bb.Write(ELEMENT_TYPE_VOID); - } - else - { - WriteType(module, bb, type); - } - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/StandAloneMethodSig.cs b/mcs/class/IKVM.Reflection/StandAloneMethodSig.cs deleted file mode 100644 index 1d9425d787b..00000000000 --- a/mcs/class/IKVM.Reflection/StandAloneMethodSig.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2010 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.InteropServices; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection -{ - public sealed class __StandAloneMethodSig - { - private readonly bool unmanaged; - private readonly CallingConvention unmanagedCallingConvention; - private readonly CallingConventions callingConvention; - private readonly Type returnType; - private readonly Type[] parameterTypes; - private readonly Type[] optionalParameterTypes; - private readonly PackedCustomModifiers customModifiers; - - internal __StandAloneMethodSig(bool unmanaged, CallingConvention unmanagedCallingConvention, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes, PackedCustomModifiers customModifiers) - { - this.unmanaged = unmanaged; - this.unmanagedCallingConvention = unmanagedCallingConvention; - this.callingConvention = callingConvention; - this.returnType = returnType; - this.parameterTypes = parameterTypes; - this.optionalParameterTypes = optionalParameterTypes; - this.customModifiers = customModifiers; - } - - public bool Equals(__StandAloneMethodSig other) - { - return other != null - && other.unmanaged == unmanaged - && other.unmanagedCallingConvention == unmanagedCallingConvention - && other.callingConvention == callingConvention - && other.returnType == returnType - && Util.ArrayEquals(other.parameterTypes, parameterTypes) - && Util.ArrayEquals(other.optionalParameterTypes, optionalParameterTypes) - && other.customModifiers.Equals(customModifiers); - } - - public override bool Equals(object obj) - { - return Equals(obj as __StandAloneMethodSig); - } - - public override int GetHashCode() - { - return returnType.GetHashCode() - ^ Util.GetHashCode(parameterTypes); - } - - public bool IsUnmanaged - { - get { return unmanaged; } - } - - public CallingConventions CallingConvention - { - get { return callingConvention; } - } - - public CallingConvention UnmanagedCallingConvention - { - get { return unmanagedCallingConvention; } - } - - public Type ReturnType - { - get { return returnType; } - } - - public CustomModifiers GetReturnTypeCustomModifiers() - { - return customModifiers.GetReturnTypeCustomModifiers(); - } - - public Type[] ParameterTypes - { - get { return Util.Copy(parameterTypes); } - } - - public Type[] OptionalParameterTypes - { - get { return Util.Copy(optionalParameterTypes); } - } - - public CustomModifiers GetParameterCustomModifiers(int index) - { - return customModifiers.GetParameterCustomModifiers(index); - } - - internal int ParameterCount - { - get { return parameterTypes.Length + optionalParameterTypes.Length; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/StrongNameKeyPair.cs b/mcs/class/IKVM.Reflection/StrongNameKeyPair.cs deleted file mode 100644 index 7d354475ae0..00000000000 --- a/mcs/class/IKVM.Reflection/StrongNameKeyPair.cs +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using System.Security.Cryptography; - -namespace IKVM.Reflection -{ - public sealed class StrongNameKeyPair - { - private readonly byte[] keyPairArray; - private readonly string keyPairContainer; - - public StrongNameKeyPair(string keyPairContainer) - { - if (keyPairContainer == null) - { - throw new ArgumentNullException("keyPairContainer"); - } - if (Universe.MonoRuntime && Environment.OSVersion.Platform == PlatformID.Win32NT) - { - throw new NotSupportedException("IKVM.Reflection does not support key containers when running on Mono"); - } - this.keyPairContainer = keyPairContainer; - } - - public StrongNameKeyPair(byte[] keyPairArray) - { - if (keyPairArray == null) - { - throw new ArgumentNullException("keyPairArray"); - } - this.keyPairArray = (byte[])keyPairArray.Clone(); - } - - public StrongNameKeyPair(FileStream keyPairFile) - : this(ReadAllBytes(keyPairFile)) - { - } - - private static byte[] ReadAllBytes(FileStream keyPairFile) - { - if (keyPairFile == null) - { - throw new ArgumentNullException("keyPairFile"); - } - byte[] buf = new byte[keyPairFile.Length - keyPairFile.Position]; - keyPairFile.Read(buf, 0, buf.Length); - return buf; - } - - public byte[] PublicKey - { - get - { - if (Universe.MonoRuntime) - { - // MONOBUG workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=5299 - return MonoGetPublicKey(); - } - using (RSACryptoServiceProvider rsa = CreateRSA()) - { - byte[] cspBlob = rsa.ExportCspBlob(false); - byte[] publicKey = new byte[12 + cspBlob.Length]; - Buffer.BlockCopy(cspBlob, 0, publicKey, 12, cspBlob.Length); - publicKey[1] = 36; - publicKey[4] = 4; - publicKey[5] = 128; - publicKey[8] = (byte)(cspBlob.Length >> 0); - publicKey[9] = (byte)(cspBlob.Length >> 8); - publicKey[10] = (byte)(cspBlob.Length >> 16); - publicKey[11] = (byte)(cspBlob.Length >> 24); - return publicKey; - } - } - } - - internal RSACryptoServiceProvider CreateRSA() - { - try - { - if (keyPairArray != null) - { - RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); - rsa.ImportCspBlob(keyPairArray); - return rsa; - } - else - { - CspParameters parm = new CspParameters(); - parm.KeyContainerName = keyPairContainer; - // MONOBUG Mono doesn't like it when Flags or KeyNumber are set - if (!Universe.MonoRuntime) - { - parm.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey; - parm.KeyNumber = 2; // Signature - } - return new RSACryptoServiceProvider(parm); - } - } - catch - { - throw new ArgumentException("Unable to obtain public key for StrongNameKeyPair."); - } - } - - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - private byte[] MonoGetPublicKey() - { - return keyPairArray != null - ? new System.Reflection.StrongNameKeyPair(keyPairArray).PublicKey - : new System.Reflection.StrongNameKeyPair(keyPairContainer).PublicKey; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Type.cs b/mcs/class/IKVM.Reflection/Type.cs deleted file mode 100644 index bb0273c6ad0..00000000000 --- a/mcs/class/IKVM.Reflection/Type.cs +++ /dev/null @@ -1,3000 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Runtime.InteropServices; -using System.Text; -using System.Collections.Generic; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection -{ - interface IGenericContext - { - Type GetGenericTypeArgument(int index); - Type GetGenericMethodArgument(int index); - } - - interface IGenericBinder - { - Type BindTypeParameter(Type type); - Type BindMethodParameter(Type type); - } - - public abstract class Type : MemberInfo, IGenericContext, IGenericBinder - { - public static readonly Type[] EmptyTypes = Empty.Array; - protected readonly Type underlyingType; - protected TypeFlags typeFlags; - - [Flags] - protected enum TypeFlags - { - // for use by TypeBuilder or TypeDefImpl - IsGenericTypeDefinition = 1, - - // for use by TypeBuilder - HasNestedTypes = 2, - Baked = 4, - - // for use by MissingType - ValueType = 8, - NotValueType = 16, - - // for use by TypeDefImpl, TypeBuilder or MissingType - PotentialEnumOrValueType = 32, - EnumOrValueType = 64, - - // for use by TypeDefImpl - NotGenericTypeDefinition = 128, - } - - // prevent subclassing by outsiders - internal Type() - { - this.underlyingType = this; - } - - internal Type(Type underlyingType) - { - System.Diagnostics.Debug.Assert(underlyingType.underlyingType == underlyingType); - this.underlyingType = underlyingType; - this.typeFlags = underlyingType.typeFlags; - } - - public static Binder DefaultBinder - { - get { return new DefaultBinder(); } - } - - public sealed override MemberTypes MemberType - { - get { return IsNested ? MemberTypes.NestedType : MemberTypes.TypeInfo; } - } - - public virtual string AssemblyQualifiedName - { - // NOTE the assembly name is not escaped here, only when used in a generic type instantiation - get { return this.FullName + ", " + this.Assembly.FullName; } - } - - public abstract Type BaseType - { - get; - } - - public abstract TypeAttributes Attributes - { - get; - } - - public virtual Type GetElementType() - { - return null; - } - - internal virtual void CheckBaked() - { - } - - public virtual Type[] __GetDeclaredTypes() - { - return Type.EmptyTypes; - } - - public virtual Type[] __GetDeclaredInterfaces() - { - return Type.EmptyTypes; - } - - public virtual MethodBase[] __GetDeclaredMethods() - { - return Empty.Array; - } - - public virtual __MethodImplMap __GetMethodImplMap() - { - throw new NotSupportedException(); - } - - public virtual FieldInfo[] __GetDeclaredFields() - { - return Empty.Array; - } - - public virtual EventInfo[] __GetDeclaredEvents() - { - return Empty.Array; - } - - public virtual PropertyInfo[] __GetDeclaredProperties() - { - return Empty.Array; - } - - public virtual CustomModifiers __GetCustomModifiers() - { - return new CustomModifiers(); - } - - [Obsolete("Please use __GetCustomModifiers() instead.")] - public Type[] __GetRequiredCustomModifiers() - { - return __GetCustomModifiers().GetRequired(); - } - - [Obsolete("Please use __GetCustomModifiers() instead.")] - public Type[] __GetOptionalCustomModifiers() - { - return __GetCustomModifiers().GetOptional(); - } - - public virtual __StandAloneMethodSig __MethodSignature - { - get { throw new InvalidOperationException(); } - } - - public virtual bool HasElementType - { - get { return false; } - } - - public virtual bool IsArray - { - get { return false; } - } - - public virtual bool __IsVector - { - get { return false; } - } - - public virtual bool IsByRef - { - get { return false; } - } - - public virtual bool IsPointer - { - get { return false; } - } - - public virtual bool __IsFunctionPointer - { - get { return false; } - } - - public virtual bool IsValueType - { - get - { - Type baseType = this.BaseType; - return baseType != null - && baseType.IsEnumOrValueType - && !this.IsEnumOrValueType; - } - } - - public virtual bool IsGenericParameter - { - get { return false; } - } - - public virtual int GenericParameterPosition - { - get { throw new NotSupportedException(); } - } - - public virtual MethodBase DeclaringMethod - { - get { return null; } - } - - public Type UnderlyingSystemType - { - get { return underlyingType; } - } - - public override Type DeclaringType - { - get { return null; } - } - - public virtual string __Name - { - get { throw new InvalidOperationException(); } - } - - public virtual string __Namespace - { - get { throw new InvalidOperationException(); } - } - - public abstract override string Name - { - get; - } - - public virtual string Namespace - { - get - { - if (IsNested) - { - return DeclaringType.Namespace; - } - return __Namespace; - } - } - - internal virtual int GetModuleBuilderToken() - { - throw new InvalidOperationException(); - } - - public static bool operator ==(Type t1, Type t2) - { - // Casting to object results in smaller code than calling ReferenceEquals and makes - // this method more likely to be inlined. - // On CLR v2 x86, microbenchmarks show this to be faster than calling ReferenceEquals. - return (object)t1 == (object)t2 - || ((object)t1 != null && (object)t2 != null && (object)t1.underlyingType == (object)t2.underlyingType); - } - - public static bool operator !=(Type t1, Type t2) - { - return !(t1 == t2); - } - - public bool Equals(Type type) - { - return this == type; - } - - public override bool Equals(object obj) - { - return Equals(obj as Type); - } - - public override int GetHashCode() - { - Type type = this.UnderlyingSystemType; - return ReferenceEquals(type, this) ? base.GetHashCode() : type.GetHashCode(); - } - - public virtual Type[] GetGenericArguments() - { - return Type.EmptyTypes; - } - - public virtual CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - return Empty.Array; - } - - [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")] - public Type[][] __GetGenericArgumentsRequiredCustomModifiers() - { - CustomModifiers[] customModifiers = __GetGenericArgumentsCustomModifiers(); - Type[][] array = new Type[customModifiers.Length][]; - for (int i = 0; i < array.Length; i++) - { - array[i] = customModifiers[i].GetRequired(); - } - return array; - } - - [Obsolete("Please use __GetGenericArgumentsCustomModifiers() instead")] - public Type[][] __GetGenericArgumentsOptionalCustomModifiers() - { - CustomModifiers[] customModifiers = __GetGenericArgumentsCustomModifiers(); - Type[][] array = new Type[customModifiers.Length][]; - for (int i = 0; i < array.Length; i++) - { - array[i] = customModifiers[i].GetOptional(); - } - return array; - } - - public virtual Type GetGenericTypeDefinition() - { - throw new InvalidOperationException(); - } - - public virtual StructLayoutAttribute StructLayoutAttribute - { - get { return null; } - } - - public virtual bool __GetLayout(out int packingSize, out int typeSize) - { - packingSize = 0; - typeSize = 0; - return false; - } - - public virtual bool IsGenericType - { - get { return false; } - } - - public virtual bool IsGenericTypeDefinition - { - get { return false; } - } - - // .NET 4.5 API - public virtual bool IsConstructedGenericType - { - get { return false; } - } - - public virtual bool ContainsGenericParameters - { - get - { - if (this.IsGenericParameter) - { - return true; - } - foreach (Type arg in this.GetGenericArguments()) - { - if (arg.ContainsGenericParameters) - { - return true; - } - } - return false; - } - } - - public virtual Type[] GetGenericParameterConstraints() - { - throw new InvalidOperationException(); - } - - public virtual GenericParameterAttributes GenericParameterAttributes - { - get { throw new InvalidOperationException(); } - } - - public virtual int GetArrayRank() - { - throw new NotSupportedException(); - } - - public virtual int[] __GetArraySizes() - { - throw new NotSupportedException(); - } - - public virtual int[] __GetArrayLowerBounds() - { - throw new NotSupportedException(); - } - - // .NET 4.0 API - public virtual Type GetEnumUnderlyingType() - { - if (!this.IsEnum) - { - throw new ArgumentException(); - } - CheckBaked(); - return GetEnumUnderlyingTypeImpl(); - } - - internal Type GetEnumUnderlyingTypeImpl() - { - foreach (FieldInfo field in __GetDeclaredFields()) - { - if (!field.IsStatic) - { - // the CLR assumes that an enum has only one instance field, so we can do the same - return field.FieldType; - } - } - throw new InvalidOperationException(); - } - - public override string ToString() - { - return FullName; - } - - public abstract string FullName - { - get; - } - - protected string GetFullName() - { - string ns = TypeNameParser.Escape(this.__Namespace); - Type decl = this.DeclaringType; - if (decl == null) - { - if (ns == null) - { - return this.Name; - } - else - { - return ns + "." + this.Name; - } - } - else - { - if (ns == null) - { - return decl.FullName + "+" + this.Name; - } - else - { - return decl.FullName + "+" + ns + "." + this.Name; - } - } - } - - internal virtual bool IsModulePseudoType - { - get { return false; } - } - - internal virtual Type GetGenericTypeArgument(int index) - { - throw new InvalidOperationException(); - } - - public MemberInfo[] GetDefaultMembers() - { - Type defaultMemberAttribute = this.Module.universe.Import(typeof(System.Reflection.DefaultMemberAttribute)); - foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(this)) - { - if (cad.Constructor.DeclaringType.Equals(defaultMemberAttribute)) - { - return GetMember((string)cad.ConstructorArguments[0].Value); - } - } - return Empty.Array; - } - - public MemberInfo[] GetMember(string name) - { - return GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public MemberInfo[] GetMember(string name, BindingFlags bindingAttr) - { - return GetMember(name, MemberTypes.All, bindingAttr); - } - - public MemberInfo[] GetMembers() - { - return GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public MemberInfo[] GetMembers(BindingFlags bindingAttr) - { - List members = new List(); - members.AddRange(GetConstructors(bindingAttr)); - members.AddRange(GetMethods(bindingAttr)); - members.AddRange(GetFields(bindingAttr)); - members.AddRange(GetProperties(bindingAttr)); - members.AddRange(GetEvents(bindingAttr)); - members.AddRange(GetNestedTypes(bindingAttr)); - return members.ToArray(); - } - - public MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) - { - MemberFilter filter; - if ((bindingAttr & BindingFlags.IgnoreCase) != 0) - { - name = name.ToLowerInvariant(); - filter = delegate(MemberInfo member, object filterCriteria) { return member.Name.ToLowerInvariant().Equals(filterCriteria); }; - } - else - { - filter = delegate(MemberInfo member, object filterCriteria) { return member.Name.Equals(filterCriteria); }; - } - return FindMembers(type, bindingAttr, filter, name); - } - - private static void AddMembers(List list, MemberFilter filter, object filterCriteria, MemberInfo[] members) - { - foreach (MemberInfo member in members) - { - if (filter == null || filter(member, filterCriteria)) - { - list.Add(member); - } - } - } - - public MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria) - { - List members = new List(); - if ((memberType & MemberTypes.Constructor) != 0) - { - AddMembers(members, filter, filterCriteria, GetConstructors(bindingAttr)); - } - if ((memberType & MemberTypes.Method) != 0) - { - AddMembers(members, filter, filterCriteria, GetMethods(bindingAttr)); - } - if ((memberType & MemberTypes.Field) != 0) - { - AddMembers(members, filter, filterCriteria, GetFields(bindingAttr)); - } - if ((memberType & MemberTypes.Property) != 0) - { - AddMembers(members, filter, filterCriteria, GetProperties(bindingAttr)); - } - if ((memberType & MemberTypes.Event) != 0) - { - AddMembers(members, filter, filterCriteria, GetEvents(bindingAttr)); - } - if ((memberType & MemberTypes.NestedType) != 0) - { - AddMembers(members, filter, filterCriteria, GetNestedTypes(bindingAttr)); - } - return members.ToArray(); - } - - private MemberInfo[] GetMembers() - { - if (typeof(T) == typeof(ConstructorInfo) || typeof(T) == typeof(MethodInfo)) - { - return __GetDeclaredMethods(); - } - else if (typeof(T) == typeof(FieldInfo)) - { - return __GetDeclaredFields(); - } - else if (typeof(T) == typeof(PropertyInfo)) - { - return __GetDeclaredProperties(); - } - else if (typeof(T) == typeof(EventInfo)) - { - return __GetDeclaredEvents(); - } - else if (typeof(T) == typeof(Type)) - { - return __GetDeclaredTypes(); - } - else - { - throw new InvalidOperationException(); - } - } - - private T[] GetMembers(BindingFlags flags) - where T : MemberInfo - { - CheckBaked(); - List list = new List(); - foreach (MemberInfo member in GetMembers()) - { - if (member is T && member.BindingFlagsMatch(flags)) - { - list.Add((T)member); - } - } - if ((flags & BindingFlags.DeclaredOnly) == 0) - { - for (Type type = this.BaseType; type != null; type = type.BaseType) - { - type.CheckBaked(); - foreach (MemberInfo member in type.GetMembers()) - { - if (member is T && member.BindingFlagsMatchInherited(flags)) - { - list.Add((T)member.SetReflectedType(this)); - } - } - } - } - return list.ToArray(); - } - - private T GetMemberByName(string name, BindingFlags flags, Predicate filter) - where T : MemberInfo - { - CheckBaked(); - if ((flags & BindingFlags.IgnoreCase) != 0) - { - name = name.ToLowerInvariant(); - } - T found = null; - foreach (MemberInfo member in GetMembers()) - { - if (member is T && member.BindingFlagsMatch(flags)) - { - string memberName = member.Name; - if ((flags & BindingFlags.IgnoreCase) != 0) - { - memberName = memberName.ToLowerInvariant(); - } - if (memberName == name && (filter == null || filter((T)member))) - { - if (found != null) - { - throw new AmbiguousMatchException(); - } - found = (T)member; - } - } - } - if ((flags & BindingFlags.DeclaredOnly) == 0) - { - for (Type type = this.BaseType; (found == null || typeof(T) == typeof(MethodInfo)) && type != null; type = type.BaseType) - { - type.CheckBaked(); - foreach (MemberInfo member in type.GetMembers()) - { - if (member is T && member.BindingFlagsMatchInherited(flags)) - { - string memberName = member.Name; - if ((flags & BindingFlags.IgnoreCase) != 0) - { - memberName = memberName.ToLowerInvariant(); - } - if (memberName == name && (filter == null || filter((T)member))) - { - if (found != null) - { - MethodInfo mi; - // TODO does this depend on HideBySig vs HideByName? - if ((mi = found as MethodInfo) != null - && mi.MethodSignature.MatchParameterTypes(((MethodBase)member).MethodSignature)) - { - continue; - } - throw new AmbiguousMatchException(); - } - found = (T)member.SetReflectedType(this); - } - } - } - } - } - return found; - } - - private T GetMemberByName(string name, BindingFlags flags) - where T : MemberInfo - { - return GetMemberByName(name, flags, null); - } - - public EventInfo GetEvent(string name) - { - return GetEvent(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public EventInfo GetEvent(string name, BindingFlags bindingAttr) - { - return GetMemberByName(name, bindingAttr); - } - - public EventInfo[] GetEvents() - { - return GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public EventInfo[] GetEvents(BindingFlags bindingAttr) - { - return GetMembers(bindingAttr); - } - - public FieldInfo GetField(string name) - { - return GetField(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public FieldInfo GetField(string name, BindingFlags bindingAttr) - { - return GetMemberByName(name, bindingAttr); - } - - public FieldInfo[] GetFields() - { - return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); - } - - public FieldInfo[] GetFields(BindingFlags bindingAttr) - { - return GetMembers(bindingAttr); - } - - public Type[] GetInterfaces() - { - List list = new List(); - for (Type type = this; type != null; type = type.BaseType) - { - AddInterfaces(list, type); - } - return list.ToArray(); - } - - private static void AddInterfaces(List list, Type type) - { - foreach (Type iface in type.__GetDeclaredInterfaces()) - { - if (!list.Contains(iface)) - { - list.Add(iface); - AddInterfaces(list, iface); - } - } - } - - public MethodInfo[] GetMethods(BindingFlags bindingAttr) - { - CheckBaked(); - List list = new List(); - foreach (MethodBase mb in __GetDeclaredMethods()) - { - MethodInfo mi = mb as MethodInfo; - if (mi != null && mi.BindingFlagsMatch(bindingAttr)) - { - list.Add(mi); - } - } - if ((bindingAttr & BindingFlags.DeclaredOnly) == 0) - { - List baseMethods = new List(); - foreach (MethodInfo mi in list) - { - if (mi.IsVirtual) - { - baseMethods.Add(mi.GetBaseDefinition()); - } - } - for (Type type = this.BaseType; type != null; type = type.BaseType) - { - type.CheckBaked(); - foreach (MethodBase mb in type.__GetDeclaredMethods()) - { - MethodInfo mi = mb as MethodInfo; - if (mi != null && mi.BindingFlagsMatchInherited(bindingAttr)) - { - if (mi.IsVirtual) - { - if (baseMethods == null) - { - baseMethods = new List(); - } - else if (baseMethods.Contains(mi.GetBaseDefinition())) - { - continue; - } - baseMethods.Add(mi.GetBaseDefinition()); - } - list.Add((MethodInfo)mi.SetReflectedType(this)); - } - } - } - } - return list.ToArray(); - } - - public MethodInfo[] GetMethods() - { - return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); - } - - public MethodInfo GetMethod(string name) - { - return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr) - { - return GetMemberByName(name, bindingAttr); - } - - public MethodInfo GetMethod(string name, Type[] types) - { - return GetMethod(name, types, null); - } - - public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) - { - return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, types, modifiers); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - { - // first we try an exact match and only if that fails we fall back to using the binder - return GetMemberByName(name, bindingAttr, - delegate(MethodInfo method) { return method.MethodSignature.MatchParameterTypes(types); }) - ?? GetMethodWithBinder(name, bindingAttr, binder ?? DefaultBinder, types, modifiers); - } - - private T GetMethodWithBinder(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - where T : MethodBase - { - List list = new List(); - GetMemberByName(name, bindingAttr, delegate(T method) { - list.Add(method); - return false; - }); - return (T)binder.SelectMethod(bindingAttr, list.ToArray(), types, modifiers); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) - { - // FXBUG callConvention seems to be ignored - return GetMethod(name, bindingAttr, binder, types, modifiers); - } - - public ConstructorInfo[] GetConstructors() - { - return GetConstructors(BindingFlags.Public | BindingFlags.Instance); - } - - public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) - { - return GetMembers(bindingAttr | BindingFlags.DeclaredOnly); - } - - public ConstructorInfo GetConstructor(Type[] types) - { - return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, types, null); - } - - public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - { - ConstructorInfo ci1 = null; - if ((bindingAttr & BindingFlags.Instance) != 0) - { - ci1 = GetConstructorImpl(ConstructorInfo.ConstructorName, bindingAttr, binder, types, modifiers); - } - if ((bindingAttr & BindingFlags.Static) != 0) - { - ConstructorInfo ci2 = GetConstructorImpl(ConstructorInfo.TypeConstructorName, bindingAttr, binder, types, modifiers); - if (ci2 != null) - { - if (ci1 != null) - { - throw new AmbiguousMatchException(); - } - return ci2; - } - } - return ci1; - } - - private ConstructorInfo GetConstructorImpl(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - { - // first we try an exact match and only if that fails we fall back to using the binder - return GetMemberByName(name, bindingAttr | BindingFlags.DeclaredOnly, - delegate(ConstructorInfo ctor) { return ctor.MethodSignature.MatchParameterTypes(types); }) - ?? GetMethodWithBinder(name, bindingAttr, binder ?? DefaultBinder, types, modifiers); - } - - public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers) - { - // FXBUG callConvention seems to be ignored - return GetConstructor(bindingAttr, binder, types, modifiers); - } - - internal Type ResolveNestedType(TypeName typeName) - { - return FindNestedType(typeName) ?? Module.universe.GetMissingTypeOrThrow(Module, this, typeName); - } - - // unlike the public API, this takes the namespace and name into account - internal virtual Type FindNestedType(TypeName name) - { - foreach (Type type in __GetDeclaredTypes()) - { - if (type.__Namespace == name.Namespace && type.__Name == name.Name) - { - return type; - } - } - return null; - } - - internal virtual Type FindNestedTypeIgnoreCase(TypeName lowerCaseName) - { - foreach (Type type in __GetDeclaredTypes()) - { - if (new TypeName(type.__Namespace, type.__Name).ToLowerInvariant() == lowerCaseName) - { - return type; - } - } - return null; - } - - public Type GetNestedType(string name) - { - return GetNestedType(name, BindingFlags.Public); - } - - public Type GetNestedType(string name, BindingFlags bindingAttr) - { - // FXBUG the namespace is ignored, so we can use GetMemberByName - return GetMemberByName(name, bindingAttr | BindingFlags.DeclaredOnly); - } - - public Type[] GetNestedTypes() - { - return GetNestedTypes(BindingFlags.Public); - } - - public Type[] GetNestedTypes(BindingFlags bindingAttr) - { - // FXBUG the namespace is ignored, so we can use GetMember - return GetMembers(bindingAttr | BindingFlags.DeclaredOnly); - } - - public PropertyInfo[] GetProperties() - { - return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public PropertyInfo[] GetProperties(BindingFlags bindingAttr) - { - return GetMembers(bindingAttr); - } - - public PropertyInfo GetProperty(string name) - { - return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) - { - return GetMemberByName(name, bindingAttr); - } - - public PropertyInfo GetProperty(string name, Type returnType) - { - const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; - return GetMemberByName(name, flags, delegate(PropertyInfo prop) { return prop.PropertyType.Equals(returnType); }) - ?? GetPropertyWithBinder(name, flags, DefaultBinder, returnType, null, null); - } - - public PropertyInfo GetProperty(string name, Type[] types) - { - const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; - return GetMemberByName(name, flags, delegate(PropertyInfo prop) { return prop.PropertySignature.MatchParameterTypes(types); }) - ?? GetPropertyWithBinder(name, flags, DefaultBinder, null, types, null); - } - - public PropertyInfo GetProperty(string name, Type returnType, Type[] types) - { - return GetProperty(name, returnType, types, null); - } - - public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers); - } - - public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - return GetMemberByName(name, bindingAttr, - delegate(PropertyInfo prop) { - return prop.PropertyType.Equals(returnType) && prop.PropertySignature.MatchParameterTypes(types); - }) - ?? GetPropertyWithBinder(name, bindingAttr, binder ?? DefaultBinder, returnType, types, modifiers); - } - - private PropertyInfo GetPropertyWithBinder(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - List list = new List(); - GetMemberByName(name, bindingAttr, delegate(PropertyInfo property) { - list.Add(property); - return false; - }); - return binder.SelectProperty(bindingAttr, list.ToArray(), returnType, types, modifiers); - } - - public Type GetInterface(string name) - { - return GetInterface(name, false); - } - - public Type GetInterface(string name, bool ignoreCase) - { - if (ignoreCase) - { - name = name.ToLowerInvariant(); - } - Type found = null; - foreach (Type type in GetInterfaces()) - { - string typeName = type.FullName; - if (ignoreCase) - { - typeName = typeName.ToLowerInvariant(); - } - if (typeName == name) - { - if (found != null) - { - throw new AmbiguousMatchException(); - } - found = type; - } - } - return found; - } - - public Type[] FindInterfaces(TypeFilter filter, object filterCriteria) - { - List list = new List(); - foreach (Type type in GetInterfaces()) - { - if (filter(type, filterCriteria)) - { - list.Add(type); - } - } - return list.ToArray(); - } - - public ConstructorInfo TypeInitializer - { - get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); } - } - - public bool IsPrimitive - { - get - { - Universe u = this.Universe; - return this == u.System_Boolean - || this == u.System_Byte - || this == u.System_SByte - || this == u.System_Int16 - || this == u.System_UInt16 - || this == u.System_Int32 - || this == u.System_UInt32 - || this == u.System_Int64 - || this == u.System_UInt64 - || this == u.System_IntPtr - || this == u.System_UIntPtr - || this == u.System_Char - || this == u.System_Double - || this == u.System_Single - ; - } - } - - public bool IsEnum - { - get - { - Type baseType = this.BaseType; - return baseType != null - && baseType.IsEnumOrValueType - && baseType.__Name[0] == 'E'; - } - } - - public bool IsSealed - { - get { return (Attributes & TypeAttributes.Sealed) != 0; } - } - - public bool IsAbstract - { - get { return (Attributes & TypeAttributes.Abstract) != 0; } - } - - private bool CheckVisibility(TypeAttributes access) - { - return (Attributes & TypeAttributes.VisibilityMask) == access; - } - - public bool IsPublic - { - get { return CheckVisibility(TypeAttributes.Public); } - } - - public bool IsNestedPublic - { - get { return CheckVisibility(TypeAttributes.NestedPublic); } - } - - public bool IsNestedPrivate - { - get { return CheckVisibility(TypeAttributes.NestedPrivate); } - } - - public bool IsNestedFamily - { - get { return CheckVisibility(TypeAttributes.NestedFamily); } - } - - public bool IsNestedAssembly - { - get { return CheckVisibility(TypeAttributes.NestedAssembly); } - } - - public bool IsNestedFamANDAssem - { - get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); } - } - - public bool IsNestedFamORAssem - { - get { return CheckVisibility(TypeAttributes.NestedFamORAssem); } - } - - public bool IsNotPublic - { - get { return CheckVisibility(TypeAttributes.NotPublic); } - } - - public bool IsImport - { - get { return (Attributes & TypeAttributes.Import) != 0; } - } - - public bool IsCOMObject - { - get { return IsClass && IsImport; } - } - - public bool IsContextful - { - get { return IsSubclassOf(this.Module.universe.Import(typeof(ContextBoundObject))); } - } - - public bool IsMarshalByRef - { - get { return IsSubclassOf(this.Module.universe.Import(typeof(MarshalByRefObject))); } - } - - public virtual bool IsVisible - { - get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); } - } - - public bool IsAnsiClass - { - get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; } - } - - public bool IsUnicodeClass - { - get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; } - } - - public bool IsAutoClass - { - get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; } - } - - public bool IsAutoLayout - { - get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; } - } - - public bool IsLayoutSequential - { - get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; } - } - - public bool IsExplicitLayout - { - get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; } - } - - public bool IsSpecialName - { - get { return (Attributes & TypeAttributes.SpecialName) != 0; } - } - - public bool IsSerializable - { - get { return (Attributes & TypeAttributes.Serializable) != 0; } - } - - public bool IsClass - { - get { return !IsInterface && !IsValueType; } - } - - public bool IsInterface - { - get { return (Attributes & TypeAttributes.Interface) != 0; } - } - - public bool IsNested - { - // FXBUG we check the declaring type (like .NET) and this results - // in IsNested returning true for a generic type parameter - get { return this.DeclaringType != null; } - } - - public virtual bool __ContainsMissingType - { - get - { - if (this.__IsMissing) - { - return true; - } - foreach (Type arg in this.GetGenericArguments()) - { - if (arg.__ContainsMissingType) - { - return true; - } - } - return false; - } - } - - public Type MakeArrayType() - { - return ArrayType.Make(this, new CustomModifiers()); - } - - public Type __MakeArrayType(CustomModifiers customModifiers) - { - return ArrayType.Make(this, customModifiers); - } - - [Obsolete("Please use __MakeArrayType(CustomModifiers) instead.")] - public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __MakeArrayType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public Type MakeArrayType(int rank) - { - return __MakeArrayType(rank, new CustomModifiers()); - } - - public Type __MakeArrayType(int rank, CustomModifiers customModifiers) - { - return MultiArrayType.Make(this, rank, Empty.Array, new int[rank], customModifiers); - } - - [Obsolete("Please use __MakeArrayType(int, CustomModifiers) instead.")] - public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __MakeArrayType(rank, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, CustomModifiers customModifiers) - { - return MultiArrayType.Make(this, rank, sizes ?? Empty.Array, lobounds ?? Empty.Array, customModifiers); - } - - [Obsolete("Please use __MakeArrayType(int, int[], int[], CustomModifiers) instead.")] - public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __MakeArrayType(rank, sizes, lobounds, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public Type MakeByRefType() - { - return ByRefType.Make(this, new CustomModifiers()); - } - - public Type __MakeByRefType(CustomModifiers customModifiers) - { - return ByRefType.Make(this, customModifiers); - } - - [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")] - public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __MakeByRefType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public Type MakePointerType() - { - return PointerType.Make(this, new CustomModifiers()); - } - - public Type __MakePointerType(CustomModifiers customModifiers) - { - return PointerType.Make(this, customModifiers); - } - - [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")] - public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __MakePointerType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public Type MakeGenericType(params Type[] typeArguments) - { - return __MakeGenericType(typeArguments, null); - } - - public Type __MakeGenericType(Type[] typeArguments, CustomModifiers[] customModifiers) - { - if (!this.__IsMissing && !this.IsGenericTypeDefinition) - { - throw new InvalidOperationException(); - } - return GenericTypeInstance.Make(this, Util.Copy(typeArguments), customModifiers == null ? null : (CustomModifiers[])customModifiers.Clone()); - } - - [Obsolete("Please use __MakeGenericType(Type[], CustomModifiers[]) instead.")] - public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) - { - if (!this.__IsMissing && !this.IsGenericTypeDefinition) - { - throw new InvalidOperationException(); - } - CustomModifiers[] mods = null; - if (requiredCustomModifiers != null || optionalCustomModifiers != null) - { - mods = new CustomModifiers[typeArguments.Length]; - for (int i = 0; i < mods.Length; i++) - { - mods[i] = CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i)); - } - } - return GenericTypeInstance.Make(this, Util.Copy(typeArguments), mods); - } - - public static System.Type __GetSystemType(TypeCode typeCode) - { - switch (typeCode) - { - case TypeCode.Boolean: - return typeof(System.Boolean); - case TypeCode.Byte: - return typeof(System.Byte); - case TypeCode.Char: - return typeof(System.Char); - case TypeCode.DBNull: - return typeof(System.DBNull); - case TypeCode.DateTime: - return typeof(System.DateTime); - case TypeCode.Decimal: - return typeof(System.Decimal); - case TypeCode.Double: - return typeof(System.Double); - case TypeCode.Empty: - return null; - case TypeCode.Int16: - return typeof(System.Int16); - case TypeCode.Int32: - return typeof(System.Int32); - case TypeCode.Int64: - return typeof(System.Int64); - case TypeCode.Object: - return typeof(System.Object); - case TypeCode.SByte: - return typeof(System.SByte); - case TypeCode.Single: - return typeof(System.Single); - case TypeCode.String: - return typeof(System.String); - case TypeCode.UInt16: - return typeof(System.UInt16); - case TypeCode.UInt32: - return typeof(System.UInt32); - case TypeCode.UInt64: - return typeof(System.UInt64); - default: - throw new ArgumentOutOfRangeException(); - } - } - - public static TypeCode GetTypeCode(Type type) - { - if (type == null) - { - return TypeCode.Empty; - } - if (!type.__IsMissing && type.IsEnum) - { - type = type.GetEnumUnderlyingType(); - } - Universe u = type.Module.universe; - if (type == u.System_Boolean) - { - return TypeCode.Boolean; - } - else if (type == u.System_Char) - { - return TypeCode.Char; - } - else if (type == u.System_SByte) - { - return TypeCode.SByte; - } - else if (type == u.System_Byte) - { - return TypeCode.Byte; - } - else if (type == u.System_Int16) - { - return TypeCode.Int16; - } - else if (type == u.System_UInt16) - { - return TypeCode.UInt16; - } - else if (type == u.System_Int32) - { - return TypeCode.Int32; - } - else if (type == u.System_UInt32) - { - return TypeCode.UInt32; - } - else if (type == u.System_Int64) - { - return TypeCode.Int64; - } - else if (type == u.System_UInt64) - { - return TypeCode.UInt64; - } - else if (type == u.System_Single) - { - return TypeCode.Single; - } - else if (type == u.System_Double) - { - return TypeCode.Double; - } - else if (type == u.System_DateTime) - { - return TypeCode.DateTime; - } - else if (type == u.System_DBNull) - { - return TypeCode.DBNull; - } - else if (type == u.System_Decimal) - { - return TypeCode.Decimal; - } - else if (type == u.System_String) - { - return TypeCode.String; - } - else if (type.__IsMissing) - { - throw new MissingMemberException(type); - } - else - { - return TypeCode.Object; - } - } - - public Assembly Assembly - { - get { return Module.Assembly; } - } - - public bool IsAssignableFrom(Type type) - { - if (this.Equals(type)) - { - return true; - } - else if (type == null) - { - return false; - } - else if (this.IsArray && type.IsArray) - { - if (this.GetArrayRank() != type.GetArrayRank()) - { - return false; - } - else if (this.__IsVector && !type.__IsVector) - { - return false; - } - Type e1 = this.GetElementType(); - Type e2 = type.GetElementType(); - return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2); - } - else if (this.IsCovariant(type)) - { - return true; - } - else if (this.IsSealed) - { - return false; - } - else if (this.IsInterface) - { - foreach (Type iface in type.GetInterfaces()) - { - if (this.Equals(iface) || this.IsCovariant(iface)) - { - return true; - } - } - return false; - } - else if (type.IsInterface) - { - return this == this.Module.universe.System_Object; - } - else if (type.IsPointer) - { - return this == this.Module.universe.System_Object || this == this.Module.universe.System_ValueType; - } - else - { - return type.IsSubclassOf(this); - } - } - - private bool IsCovariant(Type other) - { - if (this.IsConstructedGenericType - && other.IsConstructedGenericType - && this.GetGenericTypeDefinition() == other.GetGenericTypeDefinition()) - { - Type[] typeParameters = GetGenericTypeDefinition().GetGenericArguments(); - for (int i = 0; i < typeParameters.Length; i++) - { - Type t1 = this.GetGenericTypeArgument(i); - Type t2 = other.GetGenericTypeArgument(i); - if (t1.IsValueType != t2.IsValueType) - { - return false; - } - switch (typeParameters[i].GenericParameterAttributes & GenericParameterAttributes.VarianceMask) - { - case GenericParameterAttributes.Covariant: - if (!t1.IsAssignableFrom(t2)) - { - return false; - } - break; - case GenericParameterAttributes.Contravariant: - if (!t2.IsAssignableFrom(t1)) - { - return false; - } - break; - case GenericParameterAttributes.None: - if (t1 != t2) - { - return false; - } - break; - } - } - return true; - } - return false; - } - - public bool IsSubclassOf(Type type) - { - Type thisType = this.BaseType; - while (thisType != null) - { - if (thisType.Equals(type)) - { - return true; - } - thisType = thisType.BaseType; - } - return false; - } - - // This returns true if this type directly (i.e. not inherited from the base class) implements the interface. - // Note that a complicating factor is that the interface itself can be implemented by an interface that extends it. - private bool IsDirectlyImplementedInterface(Type interfaceType) - { - foreach (Type iface in __GetDeclaredInterfaces()) - { - if (interfaceType.IsAssignableFrom(iface)) - { - return true; - } - } - return false; - } - - public InterfaceMapping GetInterfaceMap(Type interfaceType) - { - CheckBaked(); - InterfaceMapping map = new InterfaceMapping(); - if (!IsDirectlyImplementedInterface(interfaceType)) - { - Type baseType = this.BaseType; - if (baseType == null) - { - throw new ArgumentException(); - } - else - { - map = baseType.GetInterfaceMap(interfaceType); - } - } - else - { - map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); - map.InterfaceType = interfaceType; - map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length]; - FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods); - MethodInfo[] methods = GetMethods(BindingFlags.Instance | BindingFlags.Public); - for (int i = 0; i < map.TargetMethods.Length; i++) - { - if (map.TargetMethods[i] == null) - { - // TODO use proper method resolution (also take into account that no implicit base class implementation is used across assembly boundaries) - for (int j = 0; j < methods.Length; j++) - { - if (methods[j].Name == map.InterfaceMethods[i].Name - && methods[j].MethodSignature.Equals(map.InterfaceMethods[i].MethodSignature)) - { - map.TargetMethods[i] = methods[j]; - } - } - } - } - for (Type baseType = this.BaseType; baseType != null && interfaceType.IsAssignableFrom(baseType); baseType = baseType.BaseType) - { - baseType.FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods); - } - } - map.TargetType = this; - return map; - } - - internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods) - { - __MethodImplMap impl = __GetMethodImplMap(); - for (int i = 0; i < impl.MethodDeclarations.Length; i++) - { - for (int j = 0; j < impl.MethodDeclarations[i].Length; j++) - { - int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]); - if (index != -1 && targetMethods[index] == null) - { - targetMethods[index] = impl.MethodBodies[i]; - } - } - } - } - - Type IGenericContext.GetGenericTypeArgument(int index) - { - return GetGenericTypeArgument(index); - } - - Type IGenericContext.GetGenericMethodArgument(int index) - { - throw new BadImageFormatException(); - } - - Type IGenericBinder.BindTypeParameter(Type type) - { - return GetGenericTypeArgument(type.GenericParameterPosition); - } - - Type IGenericBinder.BindMethodParameter(Type type) - { - throw new BadImageFormatException(); - } - - internal virtual Type BindTypeParameters(IGenericBinder binder) - { - if (IsGenericTypeDefinition) - { - Type[] args = GetGenericArguments(); - Type.InplaceBindTypeParameters(binder, args); - return GenericTypeInstance.Make(this, args, null); - } - else - { - return this; - } - } - - private static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types) - { - for (int i = 0; i < types.Length; i++) - { - types[i] = types[i].BindTypeParameters(binder); - } - } - - internal virtual MethodBase FindMethod(string name, MethodSignature signature) - { - foreach (MethodBase method in __GetDeclaredMethods()) - { - if (method.Name == name && method.MethodSignature.Equals(signature)) - { - return method; - } - } - return null; - } - - internal virtual FieldInfo FindField(string name, FieldSignature signature) - { - foreach (FieldInfo field in __GetDeclaredFields()) - { - if (field.Name == name && field.FieldSignature.Equals(signature)) - { - return field; - } - } - return null; - } - - internal bool IsAllowMultipleCustomAttribute - { - get - { - IList cad = CustomAttributeData.__GetCustomAttributes(this, this.Module.universe.System_AttributeUsageAttribute, false); - if (cad.Count == 1) - { - foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments) - { - if (arg.MemberInfo.Name == "AllowMultiple") - { - return (bool)arg.TypedValue.Value; - } - } - } - return false; - } - } - - internal bool IsPseudoCustomAttribute - { - get - { - Universe u = this.Module.universe; - return this == u.System_NonSerializedAttribute - || this == u.System_SerializableAttribute - || this == u.System_Runtime_InteropServices_DllImportAttribute - || this == u.System_Runtime_InteropServices_FieldOffsetAttribute - || this == u.System_Runtime_InteropServices_InAttribute - || this == u.System_Runtime_InteropServices_MarshalAsAttribute - || this == u.System_Runtime_InteropServices_OutAttribute - || this == u.System_Runtime_InteropServices_StructLayoutAttribute - || this == u.System_Runtime_InteropServices_OptionalAttribute - || this == u.System_Runtime_InteropServices_PreserveSigAttribute - || this == u.System_Runtime_InteropServices_ComImportAttribute - || this == u.System_Runtime_CompilerServices_SpecialNameAttribute - || this == u.System_Runtime_CompilerServices_MethodImplAttribute - ; - } - } - - internal Type MarkNotValueType() - { - typeFlags |= TypeFlags.NotValueType; - return this; - } - - internal Type MarkValueType() - { - typeFlags |= TypeFlags.ValueType; - return this; - } - - internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes) - { - Universe u = this.Module.universe; - MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, new PackedCustomModifiers(), CallingConventions.Standard | CallingConventions.HasThis, 0); - MethodBase mb = - FindMethod(".ctor", methodSig) ?? - u.GetMissingMethodOrThrow(this, ".ctor", methodSig); - return (ConstructorInfo)mb; - } - - public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length)); - } - - private MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) - { - MethodSignature sig = new MethodSignature( - returnType ?? this.Module.universe.System_Void, - Util.Copy(parameterTypes), - customModifiers, - callingConvention, - 0); - MethodInfo method = new MissingMethod(this, name, sig); - if (name == ".ctor" || name == ".cctor") - { - return new ConstructorInfoImpl(method); - } - return method; - } - - [Obsolete("Please use __CreateMissingMethod(string, CallingConventions, Type, CustomModifiers, Type[], CustomModifiers[]) instead")] - public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) - { - return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length)); - } - - public FieldInfo __CreateMissingField(string name, Type fieldType, CustomModifiers customModifiers) - { - return new MissingField(this, name, FieldSignature.Create(fieldType, customModifiers)); - } - - [Obsolete("Please use __CreateMissingField(string, Type, CustomModifiers) instead")] - public FieldInfo __CreateMissingField(string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) - { - return __CreateMissingField(name, fieldType, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers)); - } - - public PropertyInfo __CreateMissingProperty(string name, CallingConventions callingConvention, Type propertyType, CustomModifiers propertyTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - PropertySignature sig = PropertySignature.Create(callingConvention, - propertyType, - parameterTypes, - PackedCustomModifiers.CreateFromExternal(propertyTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes))); - return new MissingProperty(this, name, sig); - } - - internal virtual Type SetMetadataTokenForMissing(int token) - { - return this; - } - - protected void MarkEnumOrValueType(string typeNamespace, string typeName) - { - // we assume that mscorlib won't have nested types with these names, - // so we don't check that we're not a nested type - if (typeNamespace == "System" - && (typeName == "Enum" || typeName == "ValueType")) - { - typeFlags |= TypeFlags.PotentialEnumOrValueType; - } - } - - private bool ResolvePotentialEnumOrValueType() - { - if (this.Assembly == this.Universe.Mscorlib - || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) - // check if mscorlib forwards the type (.NETCore profile reference mscorlib forwards System.Enum and System.ValueType to System.Runtime.dll) - || this.Universe.Mscorlib.FindType(new TypeName(__Namespace, __Name)) == this) - { - typeFlags = (typeFlags & ~TypeFlags.PotentialEnumOrValueType) | TypeFlags.EnumOrValueType; - return true; - } - else - { - typeFlags &= ~TypeFlags.PotentialEnumOrValueType; - return false; - } - } - - private bool IsEnumOrValueType - { - get - { - return (typeFlags & (TypeFlags.EnumOrValueType | TypeFlags.PotentialEnumOrValueType)) != 0 - && ((typeFlags & TypeFlags.EnumOrValueType) != 0 || ResolvePotentialEnumOrValueType()); - } - } - - internal virtual Universe Universe - { - get { return Module.universe; } - } - - internal sealed override bool BindingFlagsMatch(BindingFlags flags) - { - return BindingFlagsMatch(IsNestedPublic, flags, BindingFlags.Public, BindingFlags.NonPublic); - } - - internal sealed override MemberInfo SetReflectedType(Type type) - { - throw new InvalidOperationException(); - } - - internal override int GetCurrentToken() - { - return this.MetadataToken; - } - - internal sealed override List GetPseudoCustomAttributes(Type attributeType) - { - // types don't have pseudo custom attributes - return null; - } - - // in .NET this is an extension method, but we target .NET 2.0, so we have an instance method - public TypeInfo GetTypeInfo() - { - TypeInfo type = this as TypeInfo; - if (type == null) - { - throw new MissingMemberException(this); - } - return type; - } - } - - abstract class ElementHolderType : TypeInfo - { - protected readonly Type elementType; - private int token; - private readonly CustomModifiers mods; - - protected ElementHolderType(Type elementType, CustomModifiers mods) - { - this.elementType = elementType; - this.mods = mods; - } - - protected bool EqualsHelper(ElementHolderType other) - { - return other != null - && other.elementType.Equals(elementType) - && other.mods.Equals(mods); - } - - public override CustomModifiers __GetCustomModifiers() - { - return mods; - } - - public sealed override string Name - { - get { return elementType.Name + GetSuffix(); } - } - - public sealed override string Namespace - { - get { return elementType.Namespace; } - } - - public sealed override string FullName - { - get { return elementType.FullName + GetSuffix(); } - } - - public sealed override string ToString() - { - return elementType.ToString() + GetSuffix(); - } - - public sealed override Type GetElementType() - { - return elementType; - } - - public sealed override bool HasElementType - { - get { return true; } - } - - public sealed override Module Module - { - get { return elementType.Module; } - } - - internal sealed override int GetModuleBuilderToken() - { - if (token == 0) - { - token = ((ModuleBuilder)elementType.Module).ImportType(this); - } - return token; - } - - public sealed override bool ContainsGenericParameters - { - get - { - Type type = elementType; - while (type.HasElementType) - { - type = type.GetElementType(); - } - return type.ContainsGenericParameters; - } - } - - public sealed override bool __ContainsMissingType - { - get - { - Type type = elementType; - while (type.HasElementType) - { - type = type.GetElementType(); - } - return type.__ContainsMissingType; - } - } - - internal sealed override Type BindTypeParameters(IGenericBinder binder) - { - Type type = elementType.BindTypeParameters(binder); - CustomModifiers mods = this.mods.Bind(binder); - if (ReferenceEquals(type, elementType) - && mods.Equals(this.mods)) - { - return this; - } - return Wrap(type, mods); - } - - internal override void CheckBaked() - { - elementType.CheckBaked(); - } - - internal sealed override Universe Universe - { - get { return elementType.Universe; } - } - - internal sealed override bool IsBaked - { - get { return elementType.IsBaked; } - } - - internal sealed override int GetCurrentToken() - { - // we don't have a token, so we return 0 (which is never a valid token) - return 0; - } - - internal abstract string GetSuffix(); - - protected abstract Type Wrap(Type type, CustomModifiers mods); - } - - sealed class ArrayType : ElementHolderType - { - internal static Type Make(Type type, CustomModifiers mods) - { - return type.Universe.CanonicalizeType(new ArrayType(type, mods)); - } - - private ArrayType(Type type, CustomModifiers mods) - : base(type, mods) - { - } - - public override Type BaseType - { - get { return elementType.Module.universe.System_Array; } - } - - public override Type[] __GetDeclaredInterfaces() - { - return new Type[] { - this.Module.universe.Import(typeof(IList<>)).MakeGenericType(elementType), - this.Module.universe.Import(typeof(ICollection<>)).MakeGenericType(elementType), - this.Module.universe.Import(typeof(IEnumerable<>)).MakeGenericType(elementType) - }; - } - - public override MethodBase[] __GetDeclaredMethods() - { - Type[] int32 = new Type[] { this.Module.universe.System_Int32 }; - List list = new List(); - list.Add(new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, new Type[] { this.Module.universe.System_Int32, elementType })); - list.Add(new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), int32)); - list.Add(new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32)); - list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32))); - for (Type type = elementType; type.__IsVector; type = type.GetElementType()) - { - Array.Resize(ref int32, int32.Length + 1); - int32[int32.Length - 1] = int32[0]; - list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32))); - } - return list.ToArray(); - } - - public override TypeAttributes Attributes - { - get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; } - } - - public override bool IsArray - { - get { return true; } - } - - public override bool __IsVector - { - get { return true; } - } - - public override int GetArrayRank() - { - return 1; - } - - public override bool Equals(object o) - { - return EqualsHelper(o as ArrayType); - } - - public override int GetHashCode() - { - return elementType.GetHashCode() * 5; - } - - internal override string GetSuffix() - { - return "[]"; - } - - protected override Type Wrap(Type type, CustomModifiers mods) - { - return Make(type, mods); - } - } - - sealed class MultiArrayType : ElementHolderType - { - private readonly int rank; - private readonly int[] sizes; - private readonly int[] lobounds; - - internal static Type Make(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods) - { - return type.Universe.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, mods)); - } - - private MultiArrayType(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods) - : base(type, mods) - { - this.rank = rank; - this.sizes = sizes; - this.lobounds = lobounds; - } - - public override Type BaseType - { - get { return elementType.Module.universe.System_Array; } - } - - public override MethodBase[] __GetDeclaredMethods() - { - Type int32 = this.Module.universe.System_Int32; - Type[] setArgs = new Type[rank + 1]; - Type[] getArgs = new Type[rank]; - Type[] ctorArgs = new Type[rank * 2]; - for (int i = 0; i < rank; i++) - { - setArgs[i] = int32; - getArgs[i] = int32; - ctorArgs[i * 2 + 0] = int32; - ctorArgs[i * 2 + 1] = int32; - } - setArgs[rank] = elementType; - return new MethodBase[] { - new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, getArgs)), - new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, ctorArgs)), - new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, setArgs), - new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), getArgs), - new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, getArgs), - }; - } - - public override TypeAttributes Attributes - { - get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; } - } - - public override bool IsArray - { - get { return true; } - } - - public override int GetArrayRank() - { - return rank; - } - - public override int[] __GetArraySizes() - { - return Util.Copy(sizes); - } - - public override int[] __GetArrayLowerBounds() - { - return Util.Copy(lobounds); - } - - public override bool Equals(object o) - { - MultiArrayType at = o as MultiArrayType; - return EqualsHelper(at) - && at.rank == rank - && ArrayEquals(at.sizes, sizes) - && ArrayEquals(at.lobounds, lobounds); - } - - private static bool ArrayEquals(int[] i1, int[] i2) - { - if (i1.Length == i2.Length) - { - for (int i = 0; i < i1.Length; i++) - { - if (i1[i] != i2[i]) - { - return false; - } - } - return true; - } - return false; - } - - public override int GetHashCode() - { - return elementType.GetHashCode() * 9 + rank; - } - - internal override string GetSuffix() - { - if (rank == 1) - { - return "[*]"; - } - else - { - return "[" + new String(',', rank - 1) + "]"; - } - } - - protected override Type Wrap(Type type, CustomModifiers mods) - { - return Make(type, rank, sizes, lobounds, mods); - } - } - - sealed class BuiltinArrayMethod : ArrayMethod - { - internal BuiltinArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) - : base(module, arrayClass, methodName, callingConvention, returnType, parameterTypes) - { - } - - public override MethodAttributes Attributes - { - get { return this.Name == ".ctor" ? MethodAttributes.RTSpecialName | MethodAttributes.Public : MethodAttributes.Public; } - } - - public override MethodImplAttributes GetMethodImplementationFlags() - { - return MethodImplAttributes.IL; - } - - public override int MetadataToken - { - get { return 0x06000000; } - } - - public override MethodBody GetMethodBody() - { - return null; - } - - public override ParameterInfo[] GetParameters() - { - ParameterInfo[] parameterInfos = new ParameterInfo[parameterTypes.Length]; - for (int i = 0; i < parameterInfos.Length; i++) - { - parameterInfos[i] = new ParameterInfoImpl(this, parameterTypes[i], i); - } - return parameterInfos; - } - - public override ParameterInfo ReturnParameter - { - get { return new ParameterInfoImpl(this, this.ReturnType, -1); } - } - - private sealed class ParameterInfoImpl : ParameterInfo - { - private readonly MethodInfo method; - private readonly Type type; - private readonly int pos; - - internal ParameterInfoImpl(MethodInfo method, Type type, int pos) - { - this.method = method; - this.type = type; - this.pos = pos; - } - - public override Type ParameterType - { - get { return type; } - } - - public override string Name - { - get { return null; } - } - - public override ParameterAttributes Attributes - { - get { return ParameterAttributes.None; } - } - - public override int Position - { - get { return pos; } - } - - public override object RawDefaultValue - { - get { return null; } - } - - public override CustomModifiers __GetCustomModifiers() - { - return new CustomModifiers(); - } - - public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal) - { - fieldMarshal = new FieldMarshal(); - return false; - } - - public override MemberInfo Member - { - get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; } - } - - public override int MetadataToken - { - get { return 0x08000000; } - } - - internal override Module Module - { - get { return method.Module; } - } - } - } - - sealed class ByRefType : ElementHolderType - { - internal static Type Make(Type type, CustomModifiers mods) - { - return type.Universe.CanonicalizeType(new ByRefType(type, mods)); - } - - private ByRefType(Type type, CustomModifiers mods) - : base(type, mods) - { - } - - public override bool Equals(object o) - { - return EqualsHelper(o as ByRefType); - } - - public override int GetHashCode() - { - return elementType.GetHashCode() * 3; - } - - public override Type BaseType - { - get { return null; } - } - - public override TypeAttributes Attributes - { - get { return 0; } - } - - public override bool IsByRef - { - get { return true; } - } - - internal override string GetSuffix() - { - return "&"; - } - - protected override Type Wrap(Type type, CustomModifiers mods) - { - return Make(type, mods); - } - } - - sealed class PointerType : ElementHolderType - { - internal static Type Make(Type type, CustomModifiers mods) - { - return type.Universe.CanonicalizeType(new PointerType(type, mods)); - } - - private PointerType(Type type, CustomModifiers mods) - : base(type, mods) - { - } - - public override bool Equals(object o) - { - return EqualsHelper(o as PointerType); - } - - public override int GetHashCode() - { - return elementType.GetHashCode() * 7; - } - - public override Type BaseType - { - get { return null; } - } - - public override TypeAttributes Attributes - { - get { return 0; } - } - - public override bool IsPointer - { - get { return true; } - } - - internal override string GetSuffix() - { - return "*"; - } - - protected override Type Wrap(Type type, CustomModifiers mods) - { - return Make(type, mods); - } - } - - sealed class GenericTypeInstance : TypeInfo - { - private readonly Type type; - private readonly Type[] args; - private readonly CustomModifiers[] mods; - private Type baseType; - private int token; - - internal static Type Make(Type type, Type[] typeArguments, CustomModifiers[] mods) - { - bool identity = true; - if (type is TypeBuilder || type is BakedType || type.__IsMissing) - { - // a TypeBuiler identity must be instantiated - identity = false; - } - else - { - // we must not instantiate the identity instance, because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>) - for (int i = 0; i < typeArguments.Length; i++) - { - if (typeArguments[i] != type.GetGenericTypeArgument(i) - || !IsEmpty(mods, i)) - { - identity = false; - break; - } - } - } - if (identity) - { - return type; - } - else - { - return type.Universe.CanonicalizeType(new GenericTypeInstance(type, typeArguments, mods)); - } - } - - private static bool IsEmpty(CustomModifiers[] mods, int i) - { - // we need to be extra careful, because mods doesn't not need to be in canonical format - // (Signature.ReadGenericInst() calls Make() directly, without copying the modifier arrays) - return mods == null || mods[i].IsEmpty; - } - - private GenericTypeInstance(Type type, Type[] args, CustomModifiers[] mods) - { - this.type = type; - this.args = args; - this.mods = mods; - } - - public override bool Equals(object o) - { - GenericTypeInstance gt = o as GenericTypeInstance; - return gt != null && gt.type.Equals(type) && Util.ArrayEquals(gt.args, args) - && Util.ArrayEquals(gt.mods, mods); - } - - public override int GetHashCode() - { - return type.GetHashCode() * 3 ^ Util.GetHashCode(args); - } - - public override string AssemblyQualifiedName - { - get - { - string fn = FullName; - return fn == null ? null : fn + ", " + type.Assembly.FullName; - } - } - - public override Type BaseType - { - get - { - if (baseType == null) - { - Type rawBaseType = type.BaseType; - if (rawBaseType == null) - { - baseType = rawBaseType; - } - else - { - baseType = rawBaseType.BindTypeParameters(this); - } - } - return baseType; - } - } - - public override bool IsValueType - { - get { return type.IsValueType; } - } - - public override bool IsVisible - { - get - { - if (base.IsVisible) - { - foreach (Type arg in args) - { - if (!arg.IsVisible) - { - return false; - } - } - return true; - } - return false; - } - } - - public override Type DeclaringType - { - get { return type.DeclaringType; } - } - - public override TypeAttributes Attributes - { - get { return type.Attributes; } - } - - internal override void CheckBaked() - { - type.CheckBaked(); - } - - public override FieldInfo[] __GetDeclaredFields() - { - FieldInfo[] fields = type.__GetDeclaredFields(); - for (int i = 0; i < fields.Length; i++) - { - fields[i] = fields[i].BindTypeParameters(this); - } - return fields; - } - - public override Type[] __GetDeclaredInterfaces() - { - Type[] interfaces = type.__GetDeclaredInterfaces(); - for (int i = 0; i < interfaces.Length; i++) - { - interfaces[i] = interfaces[i].BindTypeParameters(this); - } - return interfaces; - } - - public override MethodBase[] __GetDeclaredMethods() - { - MethodBase[] methods = type.__GetDeclaredMethods(); - for (int i = 0; i < methods.Length; i++) - { - methods[i] = methods[i].BindTypeParameters(this); - } - return methods; - } - - public override Type[] __GetDeclaredTypes() - { - return type.__GetDeclaredTypes(); - } - - public override EventInfo[] __GetDeclaredEvents() - { - EventInfo[] events = type.__GetDeclaredEvents(); - for (int i = 0; i < events.Length; i++) - { - events[i] = events[i].BindTypeParameters(this); - } - return events; - } - - public override PropertyInfo[] __GetDeclaredProperties() - { - PropertyInfo[] properties = type.__GetDeclaredProperties(); - for (int i = 0; i < properties.Length; i++) - { - properties[i] = properties[i].BindTypeParameters(this); - } - return properties; - } - - public override __MethodImplMap __GetMethodImplMap() - { - __MethodImplMap map = type.__GetMethodImplMap(); - map.TargetType = this; - for (int i = 0; i < map.MethodBodies.Length; i++) - { - map.MethodBodies[i] = (MethodInfo)map.MethodBodies[i].BindTypeParameters(this); - for (int j = 0; j < map.MethodDeclarations[i].Length; j++) - { - Type interfaceType = map.MethodDeclarations[i][j].DeclaringType; - if (interfaceType.IsGenericType) - { - map.MethodDeclarations[i][j] = (MethodInfo)map.MethodDeclarations[i][j].BindTypeParameters(this); - } - } - } - return map; - } - - public override string Namespace - { - get { return type.Namespace; } - } - - public override string Name - { - get { return type.Name; } - } - - public override string FullName - { - get - { - if (!this.__ContainsMissingType && this.ContainsGenericParameters) - { - return null; - } - StringBuilder sb = new StringBuilder(this.type.FullName); - sb.Append('['); - string sep = ""; - foreach (Type type in args) - { - sb.Append(sep).Append('[').Append(type.FullName).Append(", ").Append(type.Assembly.FullName.Replace("]", "\\]")).Append(']'); - sep = ","; - } - sb.Append(']'); - return sb.ToString(); - } - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(type.FullName); - sb.Append('['); - string sep = ""; - foreach (Type arg in args) - { - sb.Append(sep); - sb.Append(arg); - sep = ","; - } - sb.Append(']'); - return sb.ToString(); - } - - public override Module Module - { - get { return type.Module; } - } - - public override bool IsGenericType - { - get { return true; } - } - - public override bool IsConstructedGenericType - { - get { return true; } - } - - public override Type GetGenericTypeDefinition() - { - return type; - } - - public override Type[] GetGenericArguments() - { - return Util.Copy(args); - } - - public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() - { - return mods != null ? (CustomModifiers[])mods.Clone() : new CustomModifiers[args.Length]; - } - - internal override Type GetGenericTypeArgument(int index) - { - return args[index]; - } - - public override bool ContainsGenericParameters - { - get - { - foreach (Type type in args) - { - if (type.ContainsGenericParameters) - { - return true; - } - } - return false; - } - } - - public override bool __ContainsMissingType - { - get - { - foreach (Type type in args) - { - if (type.__ContainsMissingType) - { - return true; - } - } - return this.type.__IsMissing; - } - } - - public override StructLayoutAttribute StructLayoutAttribute - { - get { return type.StructLayoutAttribute; } - } - - internal override int GetModuleBuilderToken() - { - if (token == 0) - { - token = ((ModuleBuilder)type.Module).ImportType(this); - } - return token; - } - - internal override Type BindTypeParameters(IGenericBinder binder) - { - for (int i = 0; i < args.Length; i++) - { - Type xarg = args[i].BindTypeParameters(binder); - if (!ReferenceEquals(xarg, args[i])) - { - Type[] xargs = new Type[args.Length]; - Array.Copy(args, xargs, i); - xargs[i++] = xarg; - for (; i < args.Length; i++) - { - xargs[i] = args[i].BindTypeParameters(binder); - } - return Make(type, xargs, null); - } - } - return this; - } - - internal override int GetCurrentToken() - { - return type.GetCurrentToken(); - } - - internal override bool IsBaked - { - get { return type.IsBaked; } - } - } - - sealed class FunctionPointerType : TypeInfo - { - private readonly Universe universe; - private readonly __StandAloneMethodSig sig; - - internal static Type Make(Universe universe, __StandAloneMethodSig sig) - { - return universe.CanonicalizeType(new FunctionPointerType(universe, sig)); - } - - private FunctionPointerType(Universe universe, __StandAloneMethodSig sig) - { - this.universe = universe; - this.sig = sig; - } - - public override bool Equals(object obj) - { - FunctionPointerType other = obj as FunctionPointerType; - return other != null - && other.universe == universe - && other.sig.Equals(sig); - } - - public override int GetHashCode() - { - return sig.GetHashCode(); - } - - public override bool __IsFunctionPointer - { - get { return true; } - } - - public override __StandAloneMethodSig __MethodSignature - { - get { return sig; } - } - - public override Type BaseType - { - get { return null; } - } - - public override TypeAttributes Attributes - { - get { return 0; } - } - - public override string Name - { - get { throw new InvalidOperationException(); } - } - - public override string FullName - { - get { throw new InvalidOperationException(); } - } - - public override Module Module - { - get { throw new InvalidOperationException(); } - } - - internal override Universe Universe - { - get { return universe; } - } - - public override string ToString() - { - return ""; - } - - internal override bool IsBaked - { - get { return true; } - } - } - - sealed class MarkerType : Type - { - // used by ILGenerator - internal static readonly Type Fault = new MarkerType(); - internal static readonly Type Finally = new MarkerType(); - internal static readonly Type Filter = new MarkerType(); - // used by CustomModifiers and SignatureHelper - internal static readonly Type ModOpt = new MarkerType(); - internal static readonly Type ModReq = new MarkerType(); - // used by SignatureHelper - internal static readonly Type Sentinel = new MarkerType(); - internal static readonly Type Pinned = new MarkerType(); - - private MarkerType() { } - - public override Type BaseType - { - get { throw new InvalidOperationException(); } - } - - public override TypeAttributes Attributes - { - get { throw new InvalidOperationException(); } - } - - public override string Name - { - get { throw new InvalidOperationException(); } - } - - public override string FullName - { - get { throw new InvalidOperationException(); } - } - - public override Module Module - { - get { throw new InvalidOperationException(); } - } - - internal override bool IsBaked - { - get { throw new InvalidOperationException(); } - } - - public override bool __IsMissing - { - get { throw new InvalidOperationException(); } - } - } -} diff --git a/mcs/class/IKVM.Reflection/TypeInfo.cs b/mcs/class/IKVM.Reflection/TypeInfo.cs deleted file mode 100644 index cd1c1e17d33..00000000000 --- a/mcs/class/IKVM.Reflection/TypeInfo.cs +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright (C) 2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; - -namespace IKVM.Reflection -{ - public interface IReflectableType - { - TypeInfo GetTypeInfo(); - } - - public static class IntrospectionExtensions - { - // we target .NET 2.0 so we can't define an extension method - public static TypeInfo GetTypeInfo(/*this*/ Type type) - { - return type.GetTypeInfo(); - } - } - - public abstract class TypeInfo : Type, IReflectableType - { - private const BindingFlags Flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; - - internal TypeInfo() - { - } - - internal TypeInfo(Type underlyingType) - : base(underlyingType) - { - } - - public IEnumerable DeclaredConstructors - { - get { return GetConstructors(Flags); } - } - - public IEnumerable DeclaredEvents - { - get { return GetEvents(Flags); } - } - - public IEnumerable DeclaredFields - { - get { return GetFields(Flags); } - } - - public IEnumerable DeclaredMembers - { - get { return GetMembers(Flags); } - } - - public IEnumerable DeclaredMethods - { - get { return GetMethods(Flags); } - } - - public IEnumerable DeclaredNestedTypes - { - get - { - Type[] types = GetNestedTypes(Flags); - TypeInfo[] typeInfos = new TypeInfo[types.Length]; - for (int i = 0; i < types.Length; i++) - { - typeInfos[i] = types[i].GetTypeInfo(); - } - return typeInfos; - } - } - - public IEnumerable DeclaredProperties - { - get { return GetProperties(Flags); } - } - - public Type[] GenericTypeParameters - { - get { return IsGenericTypeDefinition ? GetGenericArguments() : Type.EmptyTypes; } - } - - public IEnumerable ImplementedInterfaces - { - get { return __GetDeclaredInterfaces(); } - } - - public Type AsType() - { - return this; - } - - public EventInfo GetDeclaredEvent(string name) - { - return GetEvent(name, Flags); - } - - public FieldInfo GetDeclaredField(string name) - { - return GetField(name, Flags); - } - - public MethodInfo GetDeclaredMethod(string name) - { - return GetMethod(name, Flags); - } - - public IEnumerable GetDeclaredMethods(string name) - { - List methods = new List(); - foreach (MethodInfo method in GetMethods(Flags)) - { - if (method.Name == name) - { - methods.Add(method); - } - } - return methods; - } - - public TypeInfo GetDeclaredNestedType(string name) - { - return GetNestedType(name, Flags).GetTypeInfo(); - } - - public PropertyInfo GetDeclaredProperty(string name) - { - return GetProperty(name, Flags); - } - - public bool IsAssignableFrom(TypeInfo typeInfo) - { - return base.IsAssignableFrom(typeInfo); - } - } -} diff --git a/mcs/class/IKVM.Reflection/TypeNameParser.cs b/mcs/class/IKVM.Reflection/TypeNameParser.cs deleted file mode 100644 index 781fe1b3588..00000000000 --- a/mcs/class/IKVM.Reflection/TypeNameParser.cs +++ /dev/null @@ -1,610 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace IKVM.Reflection -{ - // this respresents a type name as in metadata: - // - ns will be null for empty the namespace (never the empty string) - // - the strings are not escaped - struct TypeName : IEquatable - { - private readonly string ns; - private readonly string name; - - internal TypeName(string ns, string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - this.ns = ns; - this.name = name; - } - - internal string Name - { - get { return name; } - } - - internal string Namespace - { - get { return ns; } - } - - public static bool operator ==(TypeName o1, TypeName o2) - { - return o1.ns == o2.ns && o1.name == o2.name; - } - - public static bool operator !=(TypeName o1, TypeName o2) - { - return o1.ns != o2.ns || o1.name != o2.name; - } - - public override int GetHashCode() - { - return ns == null ? name.GetHashCode() : ns.GetHashCode() * 37 + name.GetHashCode(); - } - - public override bool Equals(object obj) - { - TypeName? other = obj as TypeName?; - return other != null && other.Value == this; - } - - public override string ToString() - { - return ns == null ? name : ns + "." + name; - } - - bool IEquatable.Equals(TypeName other) - { - return this == other; - } - - internal TypeName ToLowerInvariant() - { - return new TypeName(ns == null ? null : ns.ToLowerInvariant(), name.ToLowerInvariant()); - } - - internal static TypeName Split(string name) - { - int dot = name.LastIndexOf('.'); - if (dot == -1) - { - return new TypeName(null, name); - } - else - { - return new TypeName(name.Substring(0, dot), name.Substring(dot + 1)); - } - } - } - - struct TypeNameParser - { - private const string SpecialChars = "\\+,[]*&"; - private const short SZARRAY = -1; - private const short BYREF = -2; - private const short POINTER = -3; - private readonly string name; - private readonly string[] nested; - private readonly string assemblyName; - private readonly short[] modifiers; - private readonly TypeNameParser[] genericParameters; - - internal static string Escape(string name) - { - if (name == null) - { - return null; - } - StringBuilder sb = null; - for (int pos = 0; pos < name.Length; pos++) - { - char c = name[pos]; - switch (c) - { - case '\\': - case '+': - case ',': - case '[': - case ']': - case '*': - case '&': - if (sb == null) - { - sb = new StringBuilder(name, 0, pos, name.Length + 3); - } - sb.Append("\\").Append(c); - break; - default: - if (sb != null) - { - sb.Append(c); - } - break; - } - } - return sb != null ? sb.ToString() : name; - } - - internal static string Unescape(string name) - { - int pos = name.IndexOf('\\'); - if (pos == -1) - { - return name; - } - StringBuilder sb = new StringBuilder(name, 0, pos, name.Length - 1); - for (; pos < name.Length; pos++) - { - char c = name[pos]; - if (c == '\\') - { - c = name[++pos]; - } - sb.Append(c); - } - return sb.ToString(); - } - - internal static TypeNameParser Parse(string typeName, bool throwOnError) - { - if (throwOnError) - { - Parser parser = new Parser(typeName); - return new TypeNameParser(ref parser, true); - } - else - { - try - { - Parser parser = new Parser(typeName); - return new TypeNameParser(ref parser, true); - } - catch (ArgumentException) - { - return new TypeNameParser(); - } - } - } - - private TypeNameParser(ref Parser parser, bool withAssemblyName) - { - bool genericParameter = parser.pos != 0; - name = parser.NextNamePart(); - nested = null; - parser.ParseNested(ref nested); - genericParameters = null; - parser.ParseGenericParameters(ref genericParameters); - modifiers = null; - parser.ParseModifiers(ref modifiers); - assemblyName = null; - if (withAssemblyName) - { - parser.ParseAssemblyName(genericParameter, ref assemblyName); - } - } - - internal bool Error - { - get { return name == null; } - } - - internal string FirstNamePart - { - get { return name; } - } - - internal string AssemblyName - { - get { return assemblyName; } - } - - private struct Parser - { - private readonly string typeName; - internal int pos; - - internal Parser(string typeName) - { - this.typeName = typeName; - this.pos = 0; - } - - private void Check(bool condition) - { - if (!condition) - { - throw new ArgumentException("Invalid type name '" + typeName + "'"); - } - } - - private void Consume(char c) - { - Check(pos < typeName.Length && typeName[pos++] == c); - } - - private bool TryConsume(char c) - { - if (pos < typeName.Length && typeName[pos] == c) - { - pos++; - return true; - } - else - { - return false; - } - } - - internal string NextNamePart() - { - SkipWhiteSpace(); - int start = pos; - for (; pos < typeName.Length; pos++) - { - char c = typeName[pos]; - if (c == '\\') - { - pos++; - Check(pos < typeName.Length && SpecialChars.IndexOf(typeName[pos]) != -1); - } - else if (SpecialChars.IndexOf(c) != -1) - { - break; - } - } - Check(pos - start != 0); - if (start == 0 && pos == typeName.Length) - { - return typeName; - } - else - { - return typeName.Substring(start, pos - start); - } - } - - internal void ParseNested(ref string[] nested) - { - while (TryConsume('+')) - { - Add(ref nested, NextNamePart()); - } - } - - internal void ParseGenericParameters(ref TypeNameParser[] genericParameters) - { - int saved = pos; - if (TryConsume('[')) - { - SkipWhiteSpace(); - if (TryConsume(']') || TryConsume('*') || TryConsume(',')) - { - // it's not a generic parameter list, but an array instead - pos = saved; - return; - } - do - { - SkipWhiteSpace(); - if (TryConsume('[')) - { - Add(ref genericParameters, new TypeNameParser(ref this, true)); - Consume(']'); - } - else - { - Add(ref genericParameters, new TypeNameParser(ref this, false)); - } - } - while (TryConsume(',')); - Consume(']'); - SkipWhiteSpace(); - } - } - - internal void ParseModifiers(ref short[] modifiers) - { - while (pos < typeName.Length) - { - switch (typeName[pos]) - { - case '*': - pos++; - Add(ref modifiers, POINTER); - break; - case '&': - pos++; - Add(ref modifiers, BYREF); - break; - case '[': - pos++; - Add(ref modifiers, ParseArray()); - Consume(']'); - break; - default: - return; - } - SkipWhiteSpace(); - } - } - - internal void ParseAssemblyName(bool genericParameter, ref string assemblyName) - { - if (pos < typeName.Length) - { - if (typeName[pos] == ']' && genericParameter) - { - // ok - } - else - { - Consume(','); - SkipWhiteSpace(); - if (genericParameter) - { - int start = pos; - while (pos < typeName.Length) - { - char c = typeName[pos]; - if (c == '\\') - { - pos++; - // a backslash itself is not legal in an assembly name, so we don't need to check for an escaped backslash - Check(pos < typeName.Length && typeName[pos++] == ']'); - } - else if (c == ']') - { - break; - } - else - { - pos++; - } - } - Check(pos < typeName.Length && typeName[pos] == ']'); - assemblyName = typeName.Substring(start, pos - start).Replace("\\]", "]"); - } - else - { - // only when an assembly name is used in a generic type parameter, will it be escaped - assemblyName = typeName.Substring(pos); - } - Check(assemblyName.Length != 0); - } - } - else - { - Check(!genericParameter); - } - } - - private short ParseArray() - { - SkipWhiteSpace(); - Check(pos < typeName.Length); - char c = typeName[pos]; - if (c == ']') - { - return SZARRAY; - } - else if (c == '*') - { - pos++; - SkipWhiteSpace(); - return 1; - } - else - { - short rank = 1; - while (TryConsume(',')) - { - Check(rank < short.MaxValue); - rank++; - SkipWhiteSpace(); - } - return rank; - } - } - - private void SkipWhiteSpace() - { - while (pos < typeName.Length && Char.IsWhiteSpace(typeName[pos])) - { - pos++; - } - } - - private static void Add(ref T[] array, T elem) - { - if (array == null) - { - array = new T[] { elem }; - return; - } - Array.Resize(ref array, array.Length + 1); - array[array.Length - 1] = elem; - } - } - - internal Type GetType(Universe universe, Assembly context, bool throwOnError, string originalName, bool resolve, bool ignoreCase) - { - Debug.Assert(!resolve || !ignoreCase); - TypeName name = TypeName.Split(this.name); - Type type; - if (assemblyName != null) - { - Assembly asm = universe.Load(assemblyName, context, throwOnError); - if (asm == null) - { - return null; - } - if (resolve) - { - type = asm.ResolveType(name); - } - else if (ignoreCase) - { - type = asm.FindTypeIgnoreCase(name.ToLowerInvariant()); - } - else - { - type = asm.FindType(name); - } - } - else if (context == null) - { - if (resolve) - { - type = universe.Mscorlib.ResolveType(name); - } - else if (ignoreCase) - { - type = universe.Mscorlib.FindTypeIgnoreCase(name.ToLowerInvariant()); - } - else - { - type = universe.Mscorlib.FindType(name); - } - } - else - { - if (ignoreCase) - { - name = name.ToLowerInvariant(); - type = context.FindTypeIgnoreCase(name); - } - else - { - type = context.FindType(name); - } - if (type == null && context != universe.Mscorlib) - { - if (ignoreCase) - { - type = universe.Mscorlib.FindTypeIgnoreCase(name); - } - else - { - type = universe.Mscorlib.FindType(name); - } - } - if (type == null && resolve) - { - if (universe.Mscorlib.__IsMissing && !context.__IsMissing) - { - type = universe.Mscorlib.ResolveType(name); - } - else - { - type = context.ResolveType(name); - } - } - } - return Expand(type, context, throwOnError, originalName, resolve, ignoreCase); - } - - internal Type Expand(Type type, Assembly context, bool throwOnError, string originalName, bool resolve, bool ignoreCase) - { - Debug.Assert(!resolve || !ignoreCase); - if (type == null) - { - if (throwOnError) - { - throw new TypeLoadException(originalName); - } - return null; - } - if (nested != null) - { - Type outer; - foreach (string nest in nested) - { - outer = type; - TypeName name = TypeName.Split(TypeNameParser.Unescape(nest)); - type = ignoreCase - ? outer.FindNestedTypeIgnoreCase(name.ToLowerInvariant()) - : outer.FindNestedType(name); - if (type == null) - { - if (resolve) - { - type = outer.Module.universe.GetMissingTypeOrThrow(outer.Module, outer, name); - } - else if (throwOnError) - { - throw new TypeLoadException(originalName); - } - else - { - return null; - } - } - } - } - if (genericParameters != null) - { - Type[] typeArgs = new Type[genericParameters.Length]; - for (int i = 0; i < typeArgs.Length; i++) - { - typeArgs[i] = genericParameters[i].GetType(type.Assembly.universe, context, throwOnError, originalName, resolve, ignoreCase); - if (typeArgs[i] == null) - { - return null; - } - } - type = type.MakeGenericType(typeArgs); - } - if (modifiers != null) - { - foreach (short modifier in modifiers) - { - switch (modifier) - { - case SZARRAY: - type = type.MakeArrayType(); - break; - case BYREF: - type = type.MakeByRefType(); - break; - case POINTER: - type = type.MakePointerType(); - break; - default: - type = type.MakeArrayType(modifier); - break; - } - } - } - return type; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Universe.cs b/mcs/class/IKVM.Reflection/Universe.cs deleted file mode 100644 index 4999d3b4d0f..00000000000 --- a/mcs/class/IKVM.Reflection/Universe.cs +++ /dev/null @@ -1,1092 +0,0 @@ -/* - Copyright (C) 2009-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Security; -using System.Text; -using System.Diagnostics; -using IKVM.Reflection.Reader; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection -{ - public sealed class ResolveEventArgs : EventArgs - { - private readonly string name; - private readonly Assembly requestingAssembly; - - public ResolveEventArgs(string name) - : this(name, null) - { - } - - public ResolveEventArgs(string name, Assembly requestingAssembly) - { - this.name = name; - this.requestingAssembly = requestingAssembly; - } - - public string Name - { - get { return name; } - } - - public Assembly RequestingAssembly - { - get { return requestingAssembly; } - } - } - - public enum AssemblyComparisonResult - { - Unknown = 0, - EquivalentFullMatch = 1, - EquivalentWeakNamed = 2, - EquivalentFXUnified = 3, - EquivalentUnified = 4, - NonEquivalentVersion = 5, - NonEquivalent = 6, - EquivalentPartialMatch = 7, - EquivalentPartialWeakNamed = 8, - EquivalentPartialUnified = 9, - EquivalentPartialFXUnified = 10, - NonEquivalentPartialVersion = 11, - } - - public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args); - - [Flags] - public enum UniverseOptions - { - None = 0, - EnableFunctionPointers = 1, - DisableFusion = 2, - DisablePseudoCustomAttributeRetrieval = 4, - } - - public sealed class Universe : IDisposable - { - internal static readonly bool MonoRuntime = System.Type.GetType("Mono.Runtime") != null; - private readonly Dictionary canonicalizedTypes = new Dictionary(); - private readonly List assemblies = new List(); - private readonly List dynamicAssemblies = new List(); - private readonly Dictionary assembliesByName = new Dictionary(); - private readonly Dictionary importedTypes = new Dictionary(); - private Dictionary missingTypes; - private bool resolveMissingMembers; - private readonly bool enableFunctionPointers; - private readonly bool useNativeFusion; - private readonly bool returnPseudoCustomAttributes; - private Type typeof_System_Object; - private Type typeof_System_ValueType; - private Type typeof_System_Enum; - private Type typeof_System_Void; - private Type typeof_System_Boolean; - private Type typeof_System_Char; - private Type typeof_System_SByte; - private Type typeof_System_Byte; - private Type typeof_System_Int16; - private Type typeof_System_UInt16; - private Type typeof_System_Int32; - private Type typeof_System_UInt32; - private Type typeof_System_Int64; - private Type typeof_System_UInt64; - private Type typeof_System_Single; - private Type typeof_System_Double; - private Type typeof_System_String; - private Type typeof_System_IntPtr; - private Type typeof_System_UIntPtr; - private Type typeof_System_TypedReference; - private Type typeof_System_Type; - private Type typeof_System_Array; - private Type typeof_System_DateTime; - private Type typeof_System_DBNull; - private Type typeof_System_Decimal; - private Type typeof_System_NonSerializedAttribute; - private Type typeof_System_SerializableAttribute; - private Type typeof_System_AttributeUsageAttribute; - private Type typeof_System_Runtime_InteropServices_DllImportAttribute; - private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute; - private Type typeof_System_Runtime_InteropServices_InAttribute; - private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute; - private Type typeof_System_Runtime_InteropServices_UnmanagedType; - private Type typeof_System_Runtime_InteropServices_VarEnum; - private Type typeof_System_Runtime_InteropServices_OutAttribute; - private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute; - private Type typeof_System_Runtime_InteropServices_OptionalAttribute; - private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute; - private Type typeof_System_Runtime_InteropServices_CallingConvention; - private Type typeof_System_Runtime_InteropServices_CharSet; - private Type typeof_System_Runtime_InteropServices_ComImportAttribute; - private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute; - private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute; - private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute; - private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute; - private Type typeof_System_Reflection_AssemblyCopyrightAttribute; - private Type typeof_System_Reflection_AssemblyTrademarkAttribute; - private Type typeof_System_Reflection_AssemblyProductAttribute; - private Type typeof_System_Reflection_AssemblyCompanyAttribute; - private Type typeof_System_Reflection_AssemblyDescriptionAttribute; - private Type typeof_System_Reflection_AssemblyTitleAttribute; - private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute; - private Type typeof_System_Reflection_AssemblyFileVersionAttribute; - private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute; - private Type typeof_System_Security_Permissions_PermissionSetAttribute; - private Type typeof_System_Security_Permissions_SecurityAction; - private List resolvers = new List(); - private Predicate missingTypeIsValueType; - - public Universe() - : this(UniverseOptions.None) - { - } - - public Universe(UniverseOptions options) - { - enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0; - useNativeFusion = (options & UniverseOptions.DisableFusion) == 0 && GetUseNativeFusion(); - returnPseudoCustomAttributes = (options & UniverseOptions.DisablePseudoCustomAttributeRetrieval) == 0; - } - - private static bool GetUseNativeFusion() - { - try - { - return Environment.OSVersion.Platform == PlatformID.Win32NT - && !MonoRuntime - && Environment.GetEnvironmentVariable("IKVM_DISABLE_FUSION") == null; - } - catch (System.Security.SecurityException) - { - return false; - } - } - - internal Assembly Mscorlib - { - get { return Load("mscorlib"); } - } - - private Type ImportMscorlibType(System.Type type) - { - if (Mscorlib.__IsMissing) - { - return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name)); - } - // We use FindType instead of ResolveType here, because on some versions of mscorlib some of - // the special types we use/support are missing and the type properties are defined to - // return null in that case. - // Note that we don't have to unescape type.Name here, because none of the names contain special characters. - return Mscorlib.FindType(new TypeName(type.Namespace, type.Name)); - } - - private Type ResolvePrimitive(string name) - { - // Primitive here means that these types have a special metadata encoding, which means that - // there can be references to them without referring to them by name explicitly. - // We want these types to be usable even when they don't exist in mscorlib or there is no mscorlib loaded. - return Mscorlib.FindType(new TypeName("System", name)) ?? GetMissingType(Mscorlib.ManifestModule, null, new TypeName("System", name)); - } - - internal Type System_Object - { - get { return typeof_System_Object ?? (typeof_System_Object = ResolvePrimitive("Object")); } - } - - internal Type System_ValueType - { - // System.ValueType is not a primitive, but generic type parameters can have a ValueType constraint - // (we also don't want to return null here) - get { return typeof_System_ValueType ?? (typeof_System_ValueType = ResolvePrimitive("ValueType")); } - } - - internal Type System_Enum - { - // System.Enum is not a primitive, but we don't want to return null - get { return typeof_System_Enum ?? (typeof_System_Enum = ResolvePrimitive("Enum")); } - } - - internal Type System_Void - { - get { return typeof_System_Void ?? (typeof_System_Void = ResolvePrimitive("Void")); } - } - - internal Type System_Boolean - { - get { return typeof_System_Boolean ?? (typeof_System_Boolean = ResolvePrimitive("Boolean")); } - } - - internal Type System_Char - { - get { return typeof_System_Char ?? (typeof_System_Char = ResolvePrimitive("Char")); } - } - - internal Type System_SByte - { - get { return typeof_System_SByte ?? (typeof_System_SByte = ResolvePrimitive("SByte")); } - } - - internal Type System_Byte - { - get { return typeof_System_Byte ?? (typeof_System_Byte = ResolvePrimitive("Byte")); } - } - - internal Type System_Int16 - { - get { return typeof_System_Int16 ?? (typeof_System_Int16 = ResolvePrimitive("Int16")); } - } - - internal Type System_UInt16 - { - get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ResolvePrimitive("UInt16")); } - } - - internal Type System_Int32 - { - get { return typeof_System_Int32 ?? (typeof_System_Int32 = ResolvePrimitive("Int32")); } - } - - internal Type System_UInt32 - { - get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ResolvePrimitive("UInt32")); } - } - - internal Type System_Int64 - { - get { return typeof_System_Int64 ?? (typeof_System_Int64 = ResolvePrimitive("Int64")); } - } - - internal Type System_UInt64 - { - get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ResolvePrimitive("UInt64")); } - } - - internal Type System_Single - { - get { return typeof_System_Single ?? (typeof_System_Single = ResolvePrimitive("Single")); } - } - - internal Type System_Double - { - get { return typeof_System_Double ?? (typeof_System_Double = ResolvePrimitive("Double")); } - } - - internal Type System_String - { - get { return typeof_System_String ?? (typeof_System_String = ResolvePrimitive("String")); } - } - - internal Type System_IntPtr - { - get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ResolvePrimitive("IntPtr")); } - } - - internal Type System_UIntPtr - { - get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ResolvePrimitive("UIntPtr")); } - } - - internal Type System_TypedReference - { - get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ResolvePrimitive("TypedReference")); } - } - - internal Type System_Type - { - // System.Type is not a primitive, but it does have a special encoding in custom attributes - get { return typeof_System_Type ?? (typeof_System_Type = ResolvePrimitive("Type")); } - } - - internal Type System_Array - { - // System.Array is not a primitive, but it used as a base type for array types (that are primitives) - get { return typeof_System_Array ?? (typeof_System_Array = ResolvePrimitive("Array")); } - } - - internal Type System_DateTime - { - get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); } - } - - internal Type System_DBNull - { - get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); } - } - - internal Type System_Decimal - { - get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); } - } - - internal Type System_NonSerializedAttribute - { - get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); } - } - - internal Type System_SerializableAttribute - { - get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); } - } - - internal Type System_AttributeUsageAttribute - { - get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); } - } - - internal Type System_Runtime_InteropServices_DllImportAttribute - { - get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); } - } - - internal Type System_Runtime_InteropServices_FieldOffsetAttribute - { - get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); } - } - - internal Type System_Runtime_InteropServices_InAttribute - { - get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); } - } - - internal Type System_Runtime_InteropServices_MarshalAsAttribute - { - get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); } - } - - internal Type System_Runtime_InteropServices_UnmanagedType - { - get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); } - } - - internal Type System_Runtime_InteropServices_VarEnum - { - get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); } - } - - internal Type System_Runtime_InteropServices_OutAttribute - { - get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); } - } - - internal Type System_Runtime_InteropServices_StructLayoutAttribute - { - get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); } - } - - internal Type System_Runtime_InteropServices_OptionalAttribute - { - get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); } - } - - internal Type System_Runtime_InteropServices_PreserveSigAttribute - { - get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); } - } - - internal Type System_Runtime_InteropServices_CallingConvention - { - get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); } - } - - internal Type System_Runtime_InteropServices_CharSet - { - get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); } - } - - internal Type System_Runtime_InteropServices_ComImportAttribute - { - get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); } - } - - internal Type System_Runtime_CompilerServices_DecimalConstantAttribute - { - get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); } - } - - internal Type System_Runtime_CompilerServices_SpecialNameAttribute - { - get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); } - } - - internal Type System_Runtime_CompilerServices_MethodImplAttribute - { - get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); } - } - - internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute - { - get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); } - } - - internal Type System_Reflection_AssemblyCopyrightAttribute - { - get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); } - } - - internal Type System_Reflection_AssemblyTrademarkAttribute - { - get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); } - } - - internal Type System_Reflection_AssemblyProductAttribute - { - get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); } - } - - internal Type System_Reflection_AssemblyCompanyAttribute - { - get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); } - } - - internal Type System_Reflection_AssemblyDescriptionAttribute - { - get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); } - } - - internal Type System_Reflection_AssemblyTitleAttribute - { - get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); } - } - - internal Type System_Reflection_AssemblyInformationalVersionAttribute - { - get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); } - } - - internal Type System_Reflection_AssemblyFileVersionAttribute - { - get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); } - } - - internal Type System_Security_Permissions_CodeAccessSecurityAttribute - { - get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); } - } - - internal Type System_Security_Permissions_PermissionSetAttribute - { - get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); } - } - - internal Type System_Security_Permissions_SecurityAction - { - get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); } - } - - internal bool HasMscorlib - { - get { return GetLoadedAssembly("mscorlib") != null; } - } - - public event ResolveEventHandler AssemblyResolve - { - add { resolvers.Add(value); } - remove { resolvers.Remove(value); } - } - - public Type Import(System.Type type) - { - Type imported; - if (!importedTypes.TryGetValue(type, out imported)) - { - imported = ImportImpl(type); - if (imported != null) - { - importedTypes.Add(type, imported); - } - } - return imported; - } - - private Type ImportImpl(System.Type type) - { - if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly) - { - throw new ArgumentException("Did you really want to import " + type.FullName + "?"); - } - if (type.HasElementType) - { - if (type.IsArray) - { - if (type.Name.EndsWith("[]")) - { - return Import(type.GetElementType()).MakeArrayType(); - } - else - { - return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank()); - } - } - else if (type.IsByRef) - { - return Import(type.GetElementType()).MakeByRefType(); - } - else if (type.IsPointer) - { - return Import(type.GetElementType()).MakePointerType(); - } - else - { - throw new InvalidOperationException(); - } - } - else if (type.IsGenericParameter) - { - if (type.DeclaringMethod != null) - { - throw new NotImplementedException(); - } - else - { - return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition]; - } - } - else if (type.IsGenericType && !type.IsGenericTypeDefinition) - { - System.Type[] args = type.GetGenericArguments(); - Type[] importedArgs = new Type[args.Length]; - for (int i = 0; i < args.Length; i++) - { - importedArgs[i] = Import(args[i]); - } - return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs); - } - else if (type.IsNested) - { - // note that we can't pass in the namespace here, because .NET's Type.Namespace implementation is broken for nested types - // (it returns the namespace of the declaring type) - return Import(type.DeclaringType).ResolveNestedType(new TypeName(null, type.Name)); - } - else if (type.Assembly == typeof(object).Assembly) - { - // make sure mscorlib types always end up in our mscorlib - return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name)); - } - else - { - return Import(type.Assembly).ResolveType(new TypeName(type.Namespace, type.Name)); - } - } - - private Assembly Import(System.Reflection.Assembly asm) - { - return Load(asm.FullName); - } - - public RawModule OpenRawModule(string path) - { - path = Path.GetFullPath(path); - return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path); - } - - public RawModule OpenRawModule(Stream stream, string location) - { - if (!stream.CanRead || !stream.CanSeek || stream.Position != 0) - { - throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream"); - } - return new RawModule(new ModuleReader(null, this, stream, location)); - } - - public Assembly LoadAssembly(RawModule module) - { - string refname = module.GetAssemblyName().FullName; - Assembly asm = GetLoadedAssembly(refname); - if (asm == null) - { - AssemblyReader asm1 = module.ToAssembly(); - assemblies.Add(asm1); - asm = asm1; - } - return asm; - } - - public Assembly LoadFile(string path) - { - try - { - using (RawModule module = OpenRawModule(path)) - { - return LoadAssembly(module); - } - } - catch (IOException x) - { - throw new FileNotFoundException(x.Message, x); - } - catch (UnauthorizedAccessException x) - { - throw new FileNotFoundException(x.Message, x); - } - } - - private static string GetSimpleAssemblyName(string refname) - { - int pos; - string name; - if (Fusion.ParseAssemblySimpleName(refname, out pos, out name) != ParseAssemblyResult.OK) - { - throw new ArgumentException(); - } - return name; - } - - private Assembly GetLoadedAssembly(string refname) - { - Assembly asm; - if (!assembliesByName.TryGetValue(refname, out asm)) - { - string simpleName = GetSimpleAssemblyName(refname); - for (int i = 0; i < assemblies.Count; i++) - { - AssemblyComparisonResult result; - if (simpleName.Equals(assemblies[i].Name, StringComparison.InvariantCultureIgnoreCase) - && CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result)) - { - asm = assemblies[i]; - assembliesByName.Add(refname, asm); - break; - } - } - } - return asm; - } - - private Assembly GetDynamicAssembly(string refname) - { - string simpleName = GetSimpleAssemblyName(refname); - foreach (AssemblyBuilder asm in dynamicAssemblies) - { - AssemblyComparisonResult result; - if (simpleName.Equals(asm.Name, StringComparison.InvariantCultureIgnoreCase) - && CompareAssemblyIdentity(refname, false, asm.FullName, false, out result)) - { - return asm; - } - } - return null; - } - - public Assembly Load(string refname) - { - return Load(refname, null, true); - } - - internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError) - { - Assembly asm = GetLoadedAssembly(refname); - if (asm != null) - { - return asm; - } - if (resolvers.Count == 0) - { - asm = DefaultResolver(refname, throwOnError); - } - else - { - ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly); - foreach (ResolveEventHandler evt in resolvers) - { - asm = evt(this, args); - if (asm != null) - { - break; - } - } - if (asm == null) - { - asm = GetDynamicAssembly(refname); - } - } - if (asm != null) - { - string defname = asm.FullName; - if (refname != defname) - { - assembliesByName.Add(refname, asm); - } - return asm; - } - if (throwOnError) - { - throw new FileNotFoundException(refname); - } - return null; - } - - private Assembly DefaultResolver(string refname, bool throwOnError) - { - Assembly asm = GetDynamicAssembly(refname); - if (asm != null) - { - return asm; - } - string fileName; - if (throwOnError) - { - try - { - fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location; - } - catch (System.BadImageFormatException x) - { - throw new BadImageFormatException(x.Message, x); - } - } - else - { - try - { - fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location; - } - catch (System.BadImageFormatException x) - { - throw new BadImageFormatException(x.Message, x); - } - catch (FileNotFoundException) - { - // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly, - // we should throw an exception - return null; - } - } - return LoadFile(fileName); - } - - public Type GetType(string assemblyQualifiedTypeName) - { - // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(), - // import that assembly and pass it as the context, but implicitly importing is considered evil - return GetType(null, assemblyQualifiedTypeName, false, false); - } - - public Type GetType(string assemblyQualifiedTypeName, bool throwOnError) - { - // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(), - // import that assembly and pass it as the context, but implicitly importing is considered evil - return GetType(null, assemblyQualifiedTypeName, throwOnError, false); - } - - public Type GetType(string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase) - { - // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(), - // import that assembly and pass it as the context, but implicitly importing is considered evil - return GetType(null, assemblyQualifiedTypeName, throwOnError, ignoreCase); - } - - // note that context is slightly different from the calling assembly (System.Type.GetType), - // because context is passed to the AssemblyResolve event as the RequestingAssembly - public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError) - { - return GetType(context, assemblyQualifiedTypeName, throwOnError, false); - } - - // note that context is slightly different from the calling assembly (System.Type.GetType), - // because context is passed to the AssemblyResolve event as the RequestingAssembly - public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase) - { - TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError); - if (parser.Error) - { - return null; - } - return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName, false, ignoreCase); - } - - // this is similar to GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError), - // but instead it assumes that the type must exist (i.e. if EnableMissingMemberResolution is enabled - // it will create a missing type) - public Type ResolveType(Assembly context, string assemblyQualifiedTypeName) - { - TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, false); - if (parser.Error) - { - return null; - } - return parser.GetType(this, context, false, assemblyQualifiedTypeName, true, false); - } - - public Assembly[] GetAssemblies() - { - Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count]; - for (int i = 0; i < assemblies.Count; i++) - { - array[i] = assemblies[i]; - } - for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++) - { - array[j] = dynamicAssemblies[i]; - } - return array; - } - - // this is equivalent to the Fusion CompareAssemblyIdentity API - public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result) - { - return useNativeFusion - ? Fusion.CompareAssemblyIdentityNative(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result) - : Fusion.CompareAssemblyIdentityPure(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result); - } - - public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access) - { - return DefineDynamicAssemblyImpl(name, access, null, null, null, null); - } - - public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir) - { - return DefineDynamicAssemblyImpl(name, access, dir, null, null, null); - } - -#if NET_4_0 - [Obsolete] -#endif - public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) - { - return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions); - } - - private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) - { - AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions); - dynamicAssemblies.Add(asm); - return asm; - } - - internal void RenameAssembly(Assembly assembly, AssemblyName oldName) - { - List remove = new List(); - foreach (KeyValuePair kv in assembliesByName) - { - if (kv.Value == assembly) - { - remove.Add(kv.Key); - } - } - foreach (string key in remove) - { - assembliesByName.Remove(key); - } - } - - public void Dispose() - { - foreach (Assembly asm in assemblies) - { - foreach (Module mod in asm.GetLoadedModules()) - { - mod.Dispose(); - } - } - foreach (AssemblyBuilder asm in dynamicAssemblies) - { - foreach (Module mod in asm.GetLoadedModules()) - { - mod.Dispose(); - } - } - } - - public Assembly CreateMissingAssembly(string assemblyName) - { - Assembly asm = new MissingAssembly(this, assemblyName); - string name = asm.FullName; - if (!assembliesByName.ContainsKey(name)) - { - assembliesByName.Add(name, asm); - } - return asm; - } - - public void EnableMissingMemberResolution() - { - resolveMissingMembers = true; - } - - internal bool MissingMemberResolution - { - get { return resolveMissingMembers; } - } - - internal bool EnableFunctionPointers - { - get { return enableFunctionPointers; } - } - - private struct ScopedTypeName : IEquatable - { - private readonly object scope; - private readonly TypeName name; - - internal ScopedTypeName(object scope, TypeName name) - { - this.scope = scope; - this.name = name; - } - - public override bool Equals(object obj) - { - ScopedTypeName? other = obj as ScopedTypeName?; - return other != null && ((IEquatable)other.Value).Equals(this); - } - - public override int GetHashCode() - { - return scope.GetHashCode() * 7 + name.GetHashCode(); - } - - bool IEquatable.Equals(ScopedTypeName other) - { - return other.scope == scope && other.name == name; - } - } - - private Type GetMissingType(Module module, Type declaringType, TypeName typeName) - { - if (missingTypes == null) - { - missingTypes = new Dictionary(); - } - ScopedTypeName stn = new ScopedTypeName(declaringType ?? (object)module, typeName); - Type type; - if (!missingTypes.TryGetValue(stn, out type)) - { - type = new MissingType(module, declaringType, typeName.Namespace, typeName.Name); - missingTypes.Add(stn, type); - } - return type; - } - - internal Type GetMissingTypeOrThrow(Module module, Type declaringType, TypeName typeName) - { - if (resolveMissingMembers || module.Assembly.__IsMissing) - { - return GetMissingType(module, declaringType, typeName); - } - string fullName = TypeNameParser.Escape(typeName.ToString()); - if (declaringType != null) - { - fullName = declaringType.FullName + "+" + fullName; - } - throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", fullName, module.Assembly.FullName)); - } - - internal MethodBase GetMissingMethodOrThrow(Type declaringType, string name, MethodSignature signature) - { - if (resolveMissingMembers) - { - MethodInfo method = new MissingMethod(declaringType, name, signature); - if (name == ".ctor") - { - return new ConstructorInfoImpl(method); - } - return method; - } - throw new MissingMethodException(declaringType.ToString(), name); - } - - internal FieldInfo GetMissingFieldOrThrow(Type declaringType, string name, FieldSignature signature) - { - if (resolveMissingMembers) - { - return new MissingField(declaringType, name, signature); - } - throw new MissingFieldException(declaringType.ToString(), name); - } - - internal PropertyInfo GetMissingPropertyOrThrow(Type declaringType, string name, PropertySignature propertySignature) - { - // HACK we need to check __IsMissing here, because Type doesn't have a FindProperty API - // since properties are never resolved, except by custom attributes - if (resolveMissingMembers || declaringType.__IsMissing) - { - return new MissingProperty(declaringType, name, propertySignature); - } - throw new System.MissingMemberException(declaringType.ToString(), name); - } - - internal Type CanonicalizeType(Type type) - { - Type canon; - if (!canonicalizedTypes.TryGetValue(type, out canon)) - { - canon = type; - canonicalizedTypes.Add(canon, canon); - } - return canon; - } - - public Type MakeFunctionPointer(__StandAloneMethodSig sig) - { - return FunctionPointerType.Make(this, sig); - } - - public __StandAloneMethodSig MakeStandAloneMethodSig(System.Runtime.InteropServices.CallingConvention callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - return new __StandAloneMethodSig(true, callingConvention, 0, returnType ?? this.System_Void, Util.Copy(parameterTypes), Type.EmptyTypes, - PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes))); - } - - public __StandAloneMethodSig MakeStandAloneMethodSig(CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, Type[] optionalParameterTypes, CustomModifiers[] parameterTypeCustomModifiers) - { - return new __StandAloneMethodSig(false, 0, callingConvention, returnType ?? this.System_Void, Util.Copy(parameterTypes), Util.Copy(optionalParameterTypes), - PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes) + Util.NullSafeLength(optionalParameterTypes))); - } - - public event Predicate MissingTypeIsValueType - { - add - { - if (missingTypeIsValueType != null) - { - throw new InvalidOperationException("Only a single MissingTypeIsValueType handler can be registered."); - } - missingTypeIsValueType = value; - } - remove - { - if (value.Equals(missingTypeIsValueType)) - { - missingTypeIsValueType = null; - } - } - } - - internal bool ResolveMissingTypeIsValueType(MissingType missingType) - { - if (missingTypeIsValueType != null) - { - return missingTypeIsValueType(missingType); - } - throw new MissingMemberException(missingType); - } - - internal bool ReturnPseudoCustomAttributes - { - get { return returnPseudoCustomAttributes; } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Util.cs b/mcs/class/IKVM.Reflection/Util.cs deleted file mode 100644 index e05b5dbe367..00000000000 --- a/mcs/class/IKVM.Reflection/Util.cs +++ /dev/null @@ -1,256 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; - -namespace IKVM.Reflection -{ - public interface ICustomAttributeProvider - { - bool IsDefined(Type attributeType, bool inherit); - IList __GetCustomAttributes(Type attributeType, bool inherit); - } - - [Serializable] - public sealed class FileFormatLimitationExceededException : InvalidOperationException - { - public const int META_E_STRINGSPACE_FULL = unchecked((int)0x80131198); - - public FileFormatLimitationExceededException(string message, int hresult) - : base(message) - { - this.HResult = hresult; - } - - private FileFormatLimitationExceededException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) - : base(info, context) - { - } - - public int ErrorCode - { - get { return this.HResult; } - } - } - - [Serializable] - public sealed class Missing : ISerializable - { - public static readonly Missing Value = new Missing(); - - private Missing() { } - - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) - { - info.SetType(typeof(SingletonSerializationHelper)); - } - - [Serializable] - private sealed class SingletonSerializationHelper : IObjectReference - { - public object GetRealObject(StreamingContext context) - { - return Value; - } - } - } - - static class Empty - { - internal static readonly T[] Array = new T[0]; - } - - static class Util - { - internal static int[] Copy(int[] array) - { - if (array == null || array.Length == 0) - { - return Empty.Array; - } - int[] copy = new int[array.Length]; - Array.Copy(array, copy, array.Length); - return copy; - } - - internal static Type[] Copy(Type[] array) - { - if (array == null || array.Length == 0) - { - return Type.EmptyTypes; - } - Type[] copy = new Type[array.Length]; - Array.Copy(array, copy, array.Length); - return copy; - } - - internal static T[] ToArray(List list, T[] empty) where V : T - { - if (list == null || list.Count == 0) - { - return empty; - } - T[] array = new T[list.Count]; - for (int i = 0; i < array.Length; i++) - { - array[i] = list[i]; - } - return array; - } - - internal static T[] ToArray(IEnumerable values) - { - return values == null - ? Empty.Array - : new List(values).ToArray(); - } - - // note that an empty array matches a null reference - internal static bool ArrayEquals(Type[] t1, Type[] t2) - { - if (t1 == t2) - { - return true; - } - if (t1 == null) - { - return t2.Length == 0; - } - else if (t2 == null) - { - return t1.Length == 0; - } - if (t1.Length == t2.Length) - { - for (int i = 0; i < t1.Length; i++) - { - if (!TypeEquals(t1[i], t2[i])) - { - return false; - } - } - return true; - } - return false; - } - - internal static bool TypeEquals(Type t1, Type t2) - { - if (t1 == t2) - { - return true; - } - if (t1 == null) - { - return false; - } - return t1.Equals(t2); - } - - internal static int GetHashCode(Type[] types) - { - if (types == null) - { - return 0; - } - int h = 0; - foreach (Type t in types) - { - if (t != null) - { - h *= 3; - h ^= t.GetHashCode(); - } - } - return h; - } - - internal static bool ArrayEquals(CustomModifiers[] m1, CustomModifiers[] m2) - { - if (m1 == null || m2 == null) - { - return m1 == m2; - } - if (m1.Length != m2.Length) - { - return false; - } - for (int i = 0; i < m1.Length; i++) - { - if (!m1[i].Equals(m2[i])) - { - return false; - } - } - return true; - } - - internal static int GetHashCode(CustomModifiers[] mods) - { - int h = 0; - if (mods != null) - { - foreach (CustomModifiers mod in mods) - { - h ^= mod.GetHashCode(); - } - } - return h; - } - - internal static T NullSafeElementAt(T[] array, int index) - { - return array == null ? default(T) : array[index]; - } - - internal static int NullSafeLength(T[] array) - { - return array == null ? 0 : array.Length; - } - } - - [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] - struct SingleConverter - { - [System.Runtime.InteropServices.FieldOffset(0)] - private int i; - [System.Runtime.InteropServices.FieldOffset(0)] - private float f; - - internal static int SingleToInt32Bits(float v) - { - SingleConverter c = new SingleConverter(); - c.f = v; - return c.i; - } - - internal static float Int32BitsToSingle(int v) - { - SingleConverter c = new SingleConverter(); - c.i = v; - return c.f; - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/ByteBuffer.cs b/mcs/class/IKVM.Reflection/Writer/ByteBuffer.cs deleted file mode 100644 index e67bd70762a..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/ByteBuffer.cs +++ /dev/null @@ -1,341 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Writer -{ - sealed class ByteBuffer - { - private byte[] buffer; - private int pos; - private int __length; // __length is only valid if > pos, otherwise pos is the current length - - internal ByteBuffer(int initialCapacity) - { - buffer = new byte[initialCapacity]; - } - - private ByteBuffer(byte[] wrap, int length) - { - this.buffer = wrap; - this.pos = length; - } - - internal int Position - { - get { return pos; } - set - { - if (value > this.Length || value > buffer.Length) - throw new ArgumentOutOfRangeException(); - __length = Math.Max(__length, pos); - pos = value; - } - } - - internal int Length - { - get { return Math.Max(pos, __length); } - } - - // insert count bytes at the current position (without advancing the current position) - internal void Insert(int count) - { - if (count > 0) - { - int len = this.Length; - int free = buffer.Length - len; - if (free < count) - { - Grow(count - free); - } - Buffer.BlockCopy(buffer, pos, buffer, pos + count, len - pos); - __length = Math.Max(__length, pos) + count; - } - else if (count < 0) - { - throw new ArgumentOutOfRangeException("count"); - } - } - - private void Grow(int minGrow) - { - byte[] newbuf = new byte[Math.Max(buffer.Length + minGrow, buffer.Length * 2)]; - Buffer.BlockCopy(buffer, 0, newbuf, 0, buffer.Length); - buffer = newbuf; - } - - // NOTE this does not advance the position - internal int GetInt32AtCurrentPosition() - { - return buffer[pos] - + (buffer[pos + 1] << 8) - + (buffer[pos + 2] << 16) - + (buffer[pos + 3] << 24); - } - - // NOTE this does not advance the position - internal byte GetByteAtCurrentPosition() - { - return buffer[pos]; - } - - // return the number of bytes that the compressed int at the current position takes - internal int GetCompressedIntLength() - { - switch (buffer[pos] & 0xC0) - { - default: - return 1; - case 0x80: - return 2; - case 0xC0: - return 4; - } - } - - internal void Write(byte[] value) - { - if (pos + value.Length > buffer.Length) - Grow(value.Length); - Buffer.BlockCopy(value, 0, buffer, pos, value.Length); - pos += value.Length; - } - - internal void Write(byte value) - { - if (pos == buffer.Length) - Grow(1); - buffer[pos++] = value; - } - - internal void Write(sbyte value) - { - Write((byte)value); - } - - internal void Write(ushort value) - { - Write((short)value); - } - - internal void Write(short value) - { - if (pos + 2 > buffer.Length) - Grow(2); - buffer[pos++] = (byte)value; - buffer[pos++] = (byte)(value >> 8); - } - - internal void Write(uint value) - { - Write((int)value); - } - - internal void Write(int value) - { - if (pos + 4 > buffer.Length) - Grow(4); - buffer[pos++] = (byte)value; - buffer[pos++] = (byte)(value >> 8); - buffer[pos++] = (byte)(value >> 16); - buffer[pos++] = (byte)(value >> 24); - } - - internal void Write(ulong value) - { - Write((long)value); - } - - internal void Write(long value) - { - if (pos + 8 > buffer.Length) - Grow(8); - buffer[pos++] = (byte)value; - buffer[pos++] = (byte)(value >> 8); - buffer[pos++] = (byte)(value >> 16); - buffer[pos++] = (byte)(value >> 24); - buffer[pos++] = (byte)(value >> 32); - buffer[pos++] = (byte)(value >> 40); - buffer[pos++] = (byte)(value >> 48); - buffer[pos++] = (byte)(value >> 56); - } - - internal void Write(float value) - { - Write(SingleConverter.SingleToInt32Bits(value)); - } - - internal void Write(double value) - { - Write(BitConverter.DoubleToInt64Bits(value)); - } - - internal void Write(string str) - { - if (str == null) - { - Write((byte)0xFF); - } - else - { - byte[] buf = Encoding.UTF8.GetBytes(str); - WriteCompressedInt(buf.Length); - Write(buf); - } - } - - internal void WriteCompressedInt(int value) - { - if (value <= 0x7F) - { - Write((byte)value); - } - else if (value <= 0x3FFF) - { - Write((byte)(0x80 | (value >> 8))); - Write((byte)value); - } - else - { - Write((byte)(0xC0 | (value >> 24))); - Write((byte)(value >> 16)); - Write((byte)(value >> 8)); - Write((byte)value); - } - } - - internal void Write(ByteBuffer bb) - { - if (pos + bb.Length > buffer.Length) - Grow(bb.Length); - Buffer.BlockCopy(bb.buffer, 0, buffer, pos, bb.Length); - pos += bb.Length; - } - - internal void WriteTo(System.IO.Stream stream) - { - stream.Write(buffer, 0, this.Length); - } - - internal void Clear() - { - pos = 0; - __length = 0; - } - - internal void Align(int alignment) - { - if (pos + alignment > buffer.Length) - Grow(alignment); - int newpos = (pos + alignment - 1) & ~(alignment - 1); - while (pos < newpos) - buffer[pos++] = 0; - } - - internal void WriteTypeDefOrRefEncoded(int token) - { - switch (token >> 24) - { - case TypeDefTable.Index: - WriteCompressedInt((token & 0xFFFFFF) << 2 | 0); - break; - case TypeRefTable.Index: - WriteCompressedInt((token & 0xFFFFFF) << 2 | 1); - break; - case TypeSpecTable.Index: - WriteCompressedInt((token & 0xFFFFFF) << 2 | 2); - break; - default: - throw new InvalidOperationException(); - } - } - - internal void Write(System.IO.Stream stream) - { - const int chunkSize = 8192; - for (; ; ) - { - if (pos + chunkSize > buffer.Length) - Grow(chunkSize); - int read = stream.Read(buffer, pos, chunkSize); - if (read <= 0) - { - break; - } - pos += read; - } - } - - internal byte[] ToArray() - { - int len = this.Length; - byte[] buf = new byte[len]; - Buffer.BlockCopy(buffer, 0, buf, 0, len); - return buf; - } - - internal static ByteBuffer Wrap(byte[] buf) - { - return new ByteBuffer(buf, buf.Length); - } - - internal static ByteBuffer Wrap(byte[] buf, int length) - { - return new ByteBuffer(buf, length); - } - - internal bool Match(int pos, ByteBuffer bb2, int pos2, int len) - { - for (int i = 0; i < len; i++) - { - if (buffer[pos + i] != bb2.buffer[pos2 + i]) - { - return false; - } - } - return true; - } - - internal int Hash() - { - int hash = 0; - int len = this.Length; - for (int i = 0; i < len; i++) - { - hash *= 37; - hash ^= buffer[i]; - } - return hash; - } - - internal IKVM.Reflection.Reader.ByteReader GetBlob(int offset) - { - return IKVM.Reflection.Reader.ByteReader.FromBlob(buffer, offset); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/Heaps.cs b/mcs/class/IKVM.Reflection/Writer/Heaps.cs deleted file mode 100644 index 78a5d603efd..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/Heaps.cs +++ /dev/null @@ -1,395 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Writer -{ - abstract class Heap - { - protected bool frozen; - protected int unalignedlength; - - internal void Write(MetadataWriter mw) - { - int pos = mw.Position; - WriteImpl(mw); - Debug.Assert(mw.Position == pos + unalignedlength); - int align = Length - unalignedlength; - for (int i = 0; i < align; i++) - { - mw.Write((byte)0); - } - } - - internal bool IsBig - { - get { return Length > 65535; } - } - - internal int Length - { - get - { - if (!frozen) - throw new InvalidOperationException(); - return (unalignedlength + 3) & ~3; - } - } - - protected abstract void WriteImpl(MetadataWriter mw); - } - - abstract class SimpleHeap : Heap - { - internal void Freeze() - { - if (frozen) - throw new InvalidOperationException(); - frozen = true; - unalignedlength = GetLength(); - } - - protected abstract int GetLength(); - } - - sealed class TableHeap : Heap - { - internal void Freeze(MetadataWriter mw) - { - if (frozen) - throw new InvalidOperationException(); - frozen = true; - unalignedlength = GetLength(mw); - } - - protected override void WriteImpl(MetadataWriter mw) - { - Table[] tables = mw.ModuleBuilder.GetTables(); - // Header - mw.Write(0); // Reserved - int ver = mw.ModuleBuilder.MDStreamVersion; - mw.Write((byte)(ver >> 16)); // MajorVersion - mw.Write((byte)ver); // MinorVersion - byte heapSizes = 0; - if (mw.ModuleBuilder.Strings.IsBig) - { - heapSizes |= 0x01; - } - if (mw.ModuleBuilder.Guids.IsBig) - { - heapSizes |= 0x02; - } - if (mw.ModuleBuilder.Blobs.IsBig) - { - heapSizes |= 0x04; - } - mw.Write(heapSizes);// HeapSizes - // LAMESPEC spec says reserved, but .NET 2.0 Ref.Emit sets it to 0x10 - mw.Write((byte)0x10); // Reserved - long bit = 1; - long valid = 0; - foreach (Table table in tables) - { - if (table != null && table.RowCount > 0) - { - valid |= bit; - } - bit <<= 1; - } - mw.Write(valid); // Valid - mw.Write(0x0016003301FA00L); // Sorted - // Rows - foreach (Table table in tables) - { - if (table != null && table.RowCount > 0) - { - mw.Write(table.RowCount); - } - } - // Tables - foreach (Table table in tables) - { - if (table != null && table.RowCount > 0) - { - int pos = mw.Position; - table.Write(mw); - Debug.Assert(mw.Position - pos == table.GetLength(mw)); - } - } - // unexplained extra padding - mw.Write((byte)0); - } - - private static int GetLength(MetadataWriter mw) - { - int len = 4 + 4 + 8 + 8; - foreach (Table table in mw.ModuleBuilder.GetTables()) - { - if (table != null && table.RowCount > 0) - { - len += 4; // row count - len += table.GetLength(mw); - } - } - // note that we pad one extra (unexplained) byte - return len + 1; - } - } - - sealed class StringHeap : SimpleHeap - { - private List list = new List(); - private Dictionary strings = new Dictionary(); - private int nextOffset; - - internal StringHeap() - { - Add(""); - } - - internal int Add(string str) - { - Debug.Assert(!frozen); - int offset; - if (!strings.TryGetValue(str, out offset)) - { - offset = nextOffset; - nextOffset += System.Text.Encoding.UTF8.GetByteCount(str) + 1; - list.Add(str); - strings.Add(str, offset); - } - return offset; - } - - internal string Find(int index) - { - foreach (KeyValuePair kv in strings) - { - if (kv.Value == index) - { - return kv.Key; - } - } - return null; - } - - protected override int GetLength() - { - return nextOffset; - } - - protected override void WriteImpl(MetadataWriter mw) - { - foreach (string str in list) - { - mw.Write(System.Text.Encoding.UTF8.GetBytes(str)); - mw.Write((byte)0); - } - } - } - - sealed class UserStringHeap : SimpleHeap - { - private List list = new List(); - private Dictionary strings = new Dictionary(); - private int nextOffset; - - internal UserStringHeap() - { - nextOffset = 1; - } - - internal bool IsEmpty - { - get { return nextOffset == 1; } - } - - internal int Add(string str) - { - Debug.Assert(!frozen); - int offset; - if (!strings.TryGetValue(str, out offset)) - { - int length = str.Length * 2 + 1 + MetadataWriter.GetCompressedIntLength(str.Length * 2 + 1); - if (nextOffset + length > 0xFFFFFF) - { - throw new FileFormatLimitationExceededException("No logical space left to create more user strings.", FileFormatLimitationExceededException.META_E_STRINGSPACE_FULL); - } - offset = nextOffset; - nextOffset += length; - list.Add(str); - strings.Add(str, offset); - } - return offset; - } - - protected override int GetLength() - { - return nextOffset; - } - - protected override void WriteImpl(MetadataWriter mw) - { - mw.Write((byte)0); - foreach (string str in list) - { - mw.WriteCompressedInt(str.Length * 2 + 1); - byte hasSpecialChars = 0; - foreach (char ch in str) - { - mw.Write((ushort)ch); - if (hasSpecialChars == 0 && (ch < 0x20 || ch > 0x7E)) - { - if (ch > 0x7E - || (ch >= 0x01 && ch <= 0x08) - || (ch >= 0x0E && ch <= 0x1F) - || ch == 0x27 - || ch == 0x2D) - { - hasSpecialChars = 1; - } - } - } - mw.Write(hasSpecialChars); - } - } - } - - sealed class GuidHeap : SimpleHeap - { - private List list = new List(); - - internal GuidHeap() - { - } - - internal int Add(Guid guid) - { - Debug.Assert(!frozen); - list.Add(guid); - return list.Count; - } - - protected override int GetLength() - { - return list.Count * 16; - } - - protected override void WriteImpl(MetadataWriter mw) - { - foreach (Guid guid in list) - { - mw.Write(guid.ToByteArray()); - } - } - } - - sealed class BlobHeap : SimpleHeap - { - private Key[] map = new Key[8179]; - private readonly ByteBuffer buf = new ByteBuffer(32); - - private struct Key - { - internal Key[] next; - internal int len; - internal int hash; - internal int offset; - } - - internal BlobHeap() - { - buf.Write((byte)0); - } - - internal int Add(ByteBuffer bb) - { - Debug.Assert(!frozen); - int bblen = bb.Length; - if (bblen == 0) - { - return 0; - } - int lenlen = MetadataWriter.GetCompressedIntLength(bblen); - int hash = bb.Hash(); - int index = (hash & 0x7FFFFFFF) % map.Length; - Key[] keys = map; - int last = index; - while (keys[index].offset != 0) - { - if (keys[index].hash == hash - && keys[index].len == bblen - && buf.Match(keys[index].offset + lenlen, bb, 0, bblen)) - { - return keys[index].offset; - } - if (index == last) - { - if (keys[index].next == null) - { - keys[index].next = new Key[4]; - keys = keys[index].next; - index = 0; - break; - } - keys = keys[index].next; - index = -1; - last = keys.Length - 1; - } - index++; - } - int offset = buf.Position; - buf.WriteCompressedInt(bblen); - buf.Write(bb); - keys[index].len = bblen; - keys[index].hash = hash; - keys[index].offset = offset; - return offset; - } - - protected override int GetLength() - { - return buf.Position; - } - - protected override void WriteImpl(MetadataWriter mw) - { - mw.Write(buf); - } - - internal bool IsEmpty - { - get { return buf.Position == 1; } - } - - internal IKVM.Reflection.Reader.ByteReader GetBlob(int blobIndex) - { - return buf.GetBlob(blobIndex); - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/MetadataWriter.cs b/mcs/class/IKVM.Reflection/Writer/MetadataWriter.cs deleted file mode 100644 index be5ced78187..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/MetadataWriter.cs +++ /dev/null @@ -1,561 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Writer -{ - sealed class MetadataWriter : MetadataRW - { - private readonly ModuleBuilder moduleBuilder; - private readonly Stream stream; - private readonly byte[] buffer = new byte[8]; - - internal MetadataWriter(ModuleBuilder module, Stream stream) - : base(module, module.Strings.IsBig, module.Guids.IsBig, module.Blobs.IsBig) - { - this.moduleBuilder = module; - this.stream = stream; - } - - internal ModuleBuilder ModuleBuilder - { - get { return moduleBuilder; } - } - - internal int Position - { - get { return (int)stream.Position; } - } - - internal void Write(ByteBuffer bb) - { - bb.WriteTo(stream); - } - - internal void Write(byte[] value) - { - stream.Write(value, 0, value.Length); - } - - internal void Write(byte value) - { - stream.WriteByte(value); - } - - internal void Write(ushort value) - { - Write((short)value); - } - - internal void Write(short value) - { - stream.WriteByte((byte)value); - stream.WriteByte((byte)(value >> 8)); - } - - internal void Write(uint value) - { - Write((int)value); - } - - internal void Write(int value) - { - buffer[0] = (byte)value; - buffer[1] = (byte)(value >> 8); - buffer[2] = (byte)(value >> 16); - buffer[3] = (byte)(value >> 24); - stream.Write(buffer, 0, 4); - } - - internal void Write(ulong value) - { - Write((long)value); - } - - internal void Write(long value) - { - buffer[0] = (byte)value; - buffer[1] = (byte)(value >> 8); - buffer[2] = (byte)(value >> 16); - buffer[3] = (byte)(value >> 24); - buffer[4] = (byte)(value >> 32); - buffer[5] = (byte)(value >> 40); - buffer[6] = (byte)(value >> 48); - buffer[7] = (byte)(value >> 56); - stream.Write(buffer, 0, 8); - } - - internal void WriteCompressedInt(int value) - { - if (value <= 0x7F) - { - Write((byte)value); - } - else if (value <= 0x3FFF) - { - Write((byte)(0x80 | (value >> 8))); - Write((byte)value); - } - else - { - Write((byte)(0xC0 | (value >> 24))); - Write((byte)(value >> 16)); - Write((byte)(value >> 8)); - Write((byte)value); - } - } - - internal static int GetCompressedIntLength(int value) - { - if (value <= 0x7F) - { - return 1; - } - else if (value <= 0x3FFF) - { - return 2; - } - else - { - return 4; - } - } - - internal void WriteStringIndex(int index) - { - if (bigStrings) - { - Write(index); - } - else - { - Write((short)index); - } - } - - internal void WriteGuidIndex(int index) - { - if (bigGuids) - { - Write(index); - } - else - { - Write((short)index); - } - } - - internal void WriteBlobIndex(int index) - { - if (bigBlobs) - { - Write(index); - } - else - { - Write((short)index); - } - } - - internal void WriteTypeDefOrRef(int token) - { - switch (token >> 24) - { - case 0: - break; - case TypeDefTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case TypeRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case TypeSpecTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - default: - throw new InvalidOperationException(); - } - if (bigTypeDefOrRef) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteEncodedTypeDefOrRef(int encodedToken) - { - if (bigTypeDefOrRef) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteHasCustomAttribute(int token) - { - int encodedToken = CustomAttributeTable.EncodeHasCustomAttribute(token); - if (bigHasCustomAttribute) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteCustomAttributeType(int token) - { - switch (token >> 24) - { - case MethodDefTable.Index: - token = (token & 0xFFFFFF) << 3 | 2; - break; - case MemberRefTable.Index: - token = (token & 0xFFFFFF) << 3 | 3; - break; - default: - throw new InvalidOperationException(); - } - if (bigCustomAttributeType) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteField(int index) - { - if (bigField) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteMethodDef(int index) - { - if (bigMethodDef) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteParam(int index) - { - if (bigParam) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteTypeDef(int index) - { - if (bigTypeDef) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteEvent(int index) - { - if (bigEvent) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteProperty(int index) - { - if (bigProperty) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteGenericParam(int index) - { - if (bigGenericParam) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteModuleRef(int index) - { - if (bigModuleRef) - { - Write(index & 0xFFFFFF); - } - else - { - Write((short)index); - } - } - - internal void WriteResolutionScope(int token) - { - switch (token >> 24) - { - case ModuleTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case ModuleRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case AssemblyRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - case TypeRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 3; - break; - default: - throw new InvalidOperationException(); - } - if (bigResolutionScope) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteMemberRefParent(int token) - { - switch (token >> 24) - { - case TypeDefTable.Index: - token = (token & 0xFFFFFF) << 3 | 0; - break; - case TypeRefTable.Index: - token = (token & 0xFFFFFF) << 3 | 1; - break; - case ModuleRefTable.Index: - token = (token & 0xFFFFFF) << 3 | 2; - break; - case MethodDefTable.Index: - token = (token & 0xFFFFFF) << 3 | 3; - break; - case TypeSpecTable.Index: - token = (token & 0xFFFFFF) << 3 | 4; - break; - default: - throw new InvalidOperationException(); - } - if (bigMemberRefParent) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteMethodDefOrRef(int token) - { - switch (token >> 24) - { - case MethodDefTable.Index: - token = (token & 0xFFFFFF) << 1 | 0; - break; - case MemberRefTable.Index: - token = (token & 0xFFFFFF) << 1 | 1; - break; - default: - throw new InvalidOperationException(); - } - if (bigMethodDefOrRef) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteHasConstant(int token) - { - int encodedToken = ConstantTable.EncodeHasConstant(token); - if (bigHasConstant) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteHasSemantics(int encodedToken) - { - // NOTE because we've already had to do the encoding (to be able to sort the table) - // here we simple write the value - if (bigHasSemantics) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteImplementation(int token) - { - switch (token >> 24) - { - case 0: - break; - case FileTable.Index: - token = (token & 0xFFFFFF) << 2 | 0; - break; - case AssemblyRefTable.Index: - token = (token & 0xFFFFFF) << 2 | 1; - break; - case ExportedTypeTable.Index: - token = (token & 0xFFFFFF) << 2 | 2; - break; - default: - throw new InvalidOperationException(); - } - if (bigImplementation) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteTypeOrMethodDef(int encodedToken) - { - // NOTE because we've already had to do the encoding (to be able to sort the table) - // here we simple write the value - if (bigTypeOrMethodDef) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteHasDeclSecurity(int encodedToken) - { - // NOTE because we've already had to do the encoding (to be able to sort the table) - // here we simple write the value - if (bigHasDeclSecurity) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - - internal void WriteMemberForwarded(int token) - { - switch (token >> 24) - { - case FieldTable.Index: - token = (token & 0xFFFFFF) << 1 | 0; - break; - case MethodDefTable.Index: - token = (token & 0xFFFFFF) << 1 | 1; - break; - default: - throw new InvalidOperationException(); - } - if (bigMemberForwarded) - { - Write(token); - } - else - { - Write((short)token); - } - } - - internal void WriteHasFieldMarshal(int token) - { - int encodedToken = FieldMarshalTable.EncodeHasFieldMarshal(token); - if (bigHasFieldMarshal) - { - Write(encodedToken); - } - else - { - Write((short)encodedToken); - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/ModuleWriter.cs b/mcs/class/IKVM.Reflection/Writer/ModuleWriter.cs deleted file mode 100644 index 697ae974d99..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/ModuleWriter.cs +++ /dev/null @@ -1,436 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Security.Cryptography; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Impl; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Writer -{ - static class ModuleWriter - { - internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, - PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, - ResourceSection resources, int entryPointToken) - { - WriteModule(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, null); - } - - internal static void WriteModule(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, - PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, - ResourceSection resources, int entryPointToken, Stream stream) - { - if (stream == null) - { - string fileName = moduleBuilder.FullyQualifiedName; - bool mono = System.Type.GetType("Mono.Runtime") != null; - if (mono) - { - try - { - // Mono mmaps the file, so unlink the previous version since it may be in use - File.Delete(fileName); - } - catch { } - } - using (FileStream fs = new FileStream(fileName, FileMode.Create)) - { - WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, fs); - } - // if we're running on Mono, mark the module as executable by using a Mono private API extension - if (mono) - { - File.SetAttributes(fileName, (FileAttributes)(unchecked((int)0x80000000))); - } - } - else - { - WriteModuleImpl(keyPair, publicKey, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, resources, entryPointToken, stream); - } - } - - private static void WriteModuleImpl(StrongNameKeyPair keyPair, byte[] publicKey, ModuleBuilder moduleBuilder, - PEFileKinds fileKind, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine, - ResourceSection resources, int entryPointToken, Stream stream) - { - moduleBuilder.ApplyUnmanagedExports(imageFileMachine); - moduleBuilder.FixupMethodBodyTokens(); - - moduleBuilder.ModuleTable.Add(0, moduleBuilder.Strings.Add(moduleBuilder.moduleName), moduleBuilder.Guids.Add(moduleBuilder.ModuleVersionId), 0, 0); - - if (moduleBuilder.UserStrings.IsEmpty) - { - // for compat with Ref.Emit, if there aren't any user strings, we add one - moduleBuilder.UserStrings.Add(" "); - } - - if (resources != null) - { - resources.Finish(); - } - - PEWriter writer = new PEWriter(stream); - writer.Headers.OptionalHeader.FileAlignment = (uint)moduleBuilder.__FileAlignment; - switch (imageFileMachine) - { - case ImageFileMachine.I386: - writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386; - writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; - writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); - break; - case ImageFileMachine.ARM: - writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM; - writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; - writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); - break; - case ImageFileMachine.AMD64: - writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64; - writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; - writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; - writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; - writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x400000); - writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; - writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; - break; - case ImageFileMachine.IA64: - writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64; - writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; - writer.Headers.FileHeader.SizeOfOptionalHeader = 0xF0; - writer.Headers.OptionalHeader.Magic = IMAGE_OPTIONAL_HEADER.IMAGE_NT_OPTIONAL_HDR64_MAGIC; - writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x400000); - writer.Headers.OptionalHeader.SizeOfStackCommit = 0x4000; - writer.Headers.OptionalHeader.SizeOfHeapCommit = 0x2000; - break; - default: - throw new ArgumentOutOfRangeException("imageFileMachine"); - } - if (fileKind == PEFileKinds.Dll) - { - writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_DLL; - } - - switch (fileKind) - { - case PEFileKinds.WindowApplication: - writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_GUI; - break; - default: - writer.Headers.OptionalHeader.Subsystem = IMAGE_OPTIONAL_HEADER.IMAGE_SUBSYSTEM_WINDOWS_CUI; - break; - } - writer.Headers.OptionalHeader.DllCharacteristics = (ushort)moduleBuilder.__DllCharacteristics; - - CliHeader cliHeader = new CliHeader(); - cliHeader.Cb = 0x48; - cliHeader.MajorRuntimeVersion = 2; - cliHeader.MinorRuntimeVersion = moduleBuilder.MDStreamVersion < 0x20000 ? (ushort)0 : (ushort)5; - if ((portableExecutableKind & PortableExecutableKinds.ILOnly) != 0) - { - cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_ILONLY; - } - if ((portableExecutableKind & PortableExecutableKinds.Required32Bit) != 0) - { - cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_32BITREQUIRED; - } - if ((portableExecutableKind & PortableExecutableKinds.Preferred32Bit) != 0) - { - cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_32BITREQUIRED | CliHeader.COMIMAGE_FLAGS_32BITPREFERRED; - } - if (keyPair != null) - { - cliHeader.Flags |= CliHeader.COMIMAGE_FLAGS_STRONGNAMESIGNED; - } - if (moduleBuilder.IsPseudoToken(entryPointToken)) - { - entryPointToken = moduleBuilder.ResolvePseudoToken(entryPointToken); - } - cliHeader.EntryPointToken = (uint)entryPointToken; - - moduleBuilder.Strings.Freeze(); - moduleBuilder.UserStrings.Freeze(); - moduleBuilder.Guids.Freeze(); - moduleBuilder.Blobs.Freeze(); - MetadataWriter mw = new MetadataWriter(moduleBuilder, stream); - moduleBuilder.Tables.Freeze(mw); - TextSection code = new TextSection(writer, cliHeader, moduleBuilder, ComputeStrongNameSignatureLength(publicKey)); - - // Export Directory - if (code.ExportDirectoryLength != 0) - { - writer.Headers.OptionalHeader.DataDirectory[0].VirtualAddress = code.ExportDirectoryRVA; - writer.Headers.OptionalHeader.DataDirectory[0].Size = code.ExportDirectoryLength; - } - - // Import Directory - if (code.ImportDirectoryLength != 0) - { - writer.Headers.OptionalHeader.DataDirectory[1].VirtualAddress = code.ImportDirectoryRVA; - writer.Headers.OptionalHeader.DataDirectory[1].Size = code.ImportDirectoryLength; - } - - // Import Address Table Directory - if (code.ImportAddressTableLength != 0) - { - writer.Headers.OptionalHeader.DataDirectory[12].VirtualAddress = code.ImportAddressTableRVA; - writer.Headers.OptionalHeader.DataDirectory[12].Size = code.ImportAddressTableLength; - } - - // COM Descriptor Directory - writer.Headers.OptionalHeader.DataDirectory[14].VirtualAddress = code.ComDescriptorRVA; - writer.Headers.OptionalHeader.DataDirectory[14].Size = code.ComDescriptorLength; - - // Debug Directory - if (code.DebugDirectoryLength != 0) - { - writer.Headers.OptionalHeader.DataDirectory[6].VirtualAddress = code.DebugDirectoryRVA; - writer.Headers.OptionalHeader.DataDirectory[6].Size = code.DebugDirectoryLength; - } - - // we need to start by computing the number of sections, because code.PointerToRawData depends on that - writer.Headers.FileHeader.NumberOfSections = 1; - - if (moduleBuilder.initializedData.Length != 0) - { - // .sdata - writer.Headers.FileHeader.NumberOfSections++; - } - - if (resources != null) - { - // .rsrc - writer.Headers.FileHeader.NumberOfSections++; - } - - if (imageFileMachine != ImageFileMachine.ARM) - { - // .reloc - writer.Headers.FileHeader.NumberOfSections++; - } - - SectionHeader text = new SectionHeader(); - text.Name = ".text"; - text.VirtualAddress = code.BaseRVA; - text.VirtualSize = (uint)code.Length; - text.PointerToRawData = code.PointerToRawData; - text.SizeOfRawData = writer.ToFileAlignment((uint)code.Length); - text.Characteristics = SectionHeader.IMAGE_SCN_CNT_CODE | SectionHeader.IMAGE_SCN_MEM_EXECUTE | SectionHeader.IMAGE_SCN_MEM_READ; - - SectionHeader sdata = new SectionHeader(); - sdata.Name = ".sdata"; - sdata.VirtualAddress = text.VirtualAddress + writer.ToSectionAlignment(text.VirtualSize); - sdata.VirtualSize = (uint)moduleBuilder.initializedData.Length; - sdata.PointerToRawData = text.PointerToRawData + text.SizeOfRawData; - sdata.SizeOfRawData = writer.ToFileAlignment((uint)moduleBuilder.initializedData.Length); - sdata.Characteristics = SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_MEM_WRITE; - - SectionHeader rsrc = new SectionHeader(); - rsrc.Name = ".rsrc"; - rsrc.VirtualAddress = sdata.VirtualAddress + writer.ToSectionAlignment(sdata.VirtualSize); - rsrc.PointerToRawData = sdata.PointerToRawData + sdata.SizeOfRawData; - rsrc.VirtualSize = resources == null ? 0 : (uint)resources.Length; - rsrc.SizeOfRawData = writer.ToFileAlignment(rsrc.VirtualSize); - rsrc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA; - - if (rsrc.SizeOfRawData != 0) - { - // Resource Directory - writer.Headers.OptionalHeader.DataDirectory[2].VirtualAddress = rsrc.VirtualAddress; - writer.Headers.OptionalHeader.DataDirectory[2].Size = rsrc.VirtualSize; - } - - SectionHeader reloc = new SectionHeader(); - reloc.Name = ".reloc"; - reloc.VirtualAddress = rsrc.VirtualAddress + writer.ToSectionAlignment(rsrc.VirtualSize); - if (imageFileMachine != ImageFileMachine.ARM) - { - reloc.VirtualSize = ((uint)moduleBuilder.unmanagedExports.Count + 1) * 12; - } - reloc.PointerToRawData = rsrc.PointerToRawData + rsrc.SizeOfRawData; - reloc.SizeOfRawData = writer.ToFileAlignment(reloc.VirtualSize); - reloc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_DISCARDABLE; - - if (reloc.SizeOfRawData != 0) - { - // Base Relocation Directory - writer.Headers.OptionalHeader.DataDirectory[5].VirtualAddress = reloc.VirtualAddress; - writer.Headers.OptionalHeader.DataDirectory[5].Size = reloc.VirtualSize; - } - - writer.Headers.OptionalHeader.SizeOfCode = text.SizeOfRawData; - writer.Headers.OptionalHeader.SizeOfInitializedData = sdata.SizeOfRawData + rsrc.SizeOfRawData + reloc.SizeOfRawData; - writer.Headers.OptionalHeader.SizeOfUninitializedData = 0; - writer.Headers.OptionalHeader.SizeOfImage = reloc.VirtualAddress + writer.ToSectionAlignment(reloc.VirtualSize); - writer.Headers.OptionalHeader.SizeOfHeaders = text.PointerToRawData; - writer.Headers.OptionalHeader.BaseOfCode = code.BaseRVA; - writer.Headers.OptionalHeader.BaseOfData = sdata.VirtualAddress; - writer.Headers.OptionalHeader.ImageBase = (ulong)moduleBuilder.__ImageBase; - - if (imageFileMachine == ImageFileMachine.IA64) - { - // apparently for IA64 AddressOfEntryPoint points to the address of the entry point - // (i.e. there is an additional layer of indirection), so we add the offset to the pointer - writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA + 0x20; - } - else if (imageFileMachine != ImageFileMachine.ARM) - { - writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA; - } - - writer.WritePEHeaders(); - writer.WriteSectionHeader(text); - if (sdata.SizeOfRawData != 0) - { - writer.WriteSectionHeader(sdata); - } - if (rsrc.SizeOfRawData != 0) - { - writer.WriteSectionHeader(rsrc); - } - if (reloc.SizeOfRawData != 0) - { - writer.WriteSectionHeader(reloc); - } - - stream.Seek(text.PointerToRawData, SeekOrigin.Begin); - code.Write(mw, sdata.VirtualAddress); - - if (sdata.SizeOfRawData != 0) - { - stream.Seek(sdata.PointerToRawData, SeekOrigin.Begin); - mw.Write(moduleBuilder.initializedData); - } - - if (rsrc.SizeOfRawData != 0) - { - stream.Seek(rsrc.PointerToRawData, SeekOrigin.Begin); - resources.Write(mw, rsrc.VirtualAddress); - } - - if (reloc.SizeOfRawData != 0) - { - stream.Seek(reloc.PointerToRawData, SeekOrigin.Begin); - code.WriteRelocations(mw); - } - - // file alignment - stream.SetLength(reloc.PointerToRawData + reloc.SizeOfRawData); - - // do the strong naming - if (keyPair != null) - { - StrongName(stream, keyPair, writer.HeaderSize, text.PointerToRawData, code.StrongNameSignatureRVA - text.VirtualAddress + text.PointerToRawData, code.StrongNameSignatureLength); - } - - if (moduleBuilder.symbolWriter != null) - { - moduleBuilder.WriteSymbolTokenMap(); - moduleBuilder.symbolWriter.Close(); - } - } - - private static int ComputeStrongNameSignatureLength(byte[] publicKey) - { - if (publicKey == null) - { - return 0; - } - else if (publicKey.Length == 16) - { - // it must be the ECMA pseudo public key, we don't know the key size of the real key, but currently both Mono and Microsoft use a 1024 bit key size - return 128; - } - else - { - // for the supported strong naming algorithms, the signature size is the same as the key size - // (we have to subtract 32 for the header) - return publicKey.Length - 32; - } - } - - private static void StrongName(Stream stream, StrongNameKeyPair keyPair, uint headerLength, uint textSectionFileOffset, uint strongNameSignatureFileOffset, uint strongNameSignatureLength) - { - SHA1Managed hash = new SHA1Managed(); - using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write)) - { - stream.Seek(0, SeekOrigin.Begin); - byte[] buf = new byte[8192]; - HashChunk(stream, cs, buf, (int)headerLength); - stream.Seek(textSectionFileOffset, SeekOrigin.Begin); - HashChunk(stream, cs, buf, (int)(strongNameSignatureFileOffset - textSectionFileOffset)); - stream.Seek(strongNameSignatureLength, SeekOrigin.Current); - HashChunk(stream, cs, buf, (int)(stream.Length - (strongNameSignatureFileOffset + strongNameSignatureLength))); - } - using (RSA rsa = keyPair.CreateRSA()) - { - RSAPKCS1SignatureFormatter sign = new RSAPKCS1SignatureFormatter(rsa); - byte[] signature = sign.CreateSignature(hash); - Array.Reverse(signature); - if (signature.Length != strongNameSignatureLength) - { - throw new InvalidOperationException("Signature length mismatch"); - } - stream.Seek(strongNameSignatureFileOffset, SeekOrigin.Begin); - stream.Write(signature, 0, signature.Length); - } - - // compute the PE checksum - stream.Seek(0, SeekOrigin.Begin); - int count = (int)stream.Length / 4; - BinaryReader br = new BinaryReader(stream); - long sum = 0; - for (int i = 0; i < count; i++) - { - sum += br.ReadUInt32(); - int carry = (int)(sum >> 32); - sum &= 0xFFFFFFFFU; - sum += carry; - } - while ((sum >> 16) != 0) - { - sum = (sum & 0xFFFF) + (sum >> 16); - } - sum += stream.Length; - - // write the PE checksum, note that it is always at offset 0xD8 in the file - ByteBuffer bb = new ByteBuffer(4); - bb.Write((int)sum); - stream.Seek(0xD8, SeekOrigin.Begin); - bb.WriteTo(stream); - } - - internal static void HashChunk(Stream stream, CryptoStream cs, byte[] buf, int length) - { - while (length > 0) - { - int read = stream.Read(buf, 0, Math.Min(buf.Length, length)); - cs.Write(buf, 0, read); - length -= read; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/PEWriter.cs b/mcs/class/IKVM.Reflection/Writer/PEWriter.cs deleted file mode 100644 index 665296e6bd8..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/PEWriter.cs +++ /dev/null @@ -1,294 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.IO; -using BYTE = System.Byte; -using WORD = System.UInt16; -using DWORD = System.UInt32; -using ULONGLONG = System.UInt64; -using IMAGE_DATA_DIRECTORY = IKVM.Reflection.Reader.IMAGE_DATA_DIRECTORY; - -namespace IKVM.Reflection.Writer -{ - sealed class PEWriter - { - private readonly BinaryWriter bw; - private readonly IMAGE_NT_HEADERS hdr = new IMAGE_NT_HEADERS(); - - internal PEWriter(Stream stream) - { - bw = new BinaryWriter(stream); - WriteMSDOSHeader(); - } - - public IMAGE_NT_HEADERS Headers - { - get { return hdr; } - } - - public uint HeaderSize - { - get - { - return (uint) - ((8 * 16) + // MSDOS header - 4 + // signature - 20 + // IMAGE_FILE_HEADER - hdr.FileHeader.SizeOfOptionalHeader + - hdr.FileHeader.NumberOfSections * 40); - } - } - - private void WriteMSDOSHeader() - { - bw.Write(new byte[] { - 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, - 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, - 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, - 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, - 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, - 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, - 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }); - } - - internal void WritePEHeaders() - { - bw.Write(hdr.Signature); - - // IMAGE_FILE_HEADER - bw.Write(hdr.FileHeader.Machine); - bw.Write(hdr.FileHeader.NumberOfSections); - bw.Write(hdr.FileHeader.TimeDateStamp); - bw.Write(hdr.FileHeader.PointerToSymbolTable); - bw.Write(hdr.FileHeader.NumberOfSymbols); - bw.Write(hdr.FileHeader.SizeOfOptionalHeader); - bw.Write(hdr.FileHeader.Characteristics); - - // IMAGE_OPTIONAL_HEADER - hdr.OptionalHeader.Write(bw); - } - - internal void WriteSectionHeader(SectionHeader sectionHeader) - { - byte[] name = new byte[8]; - System.Text.Encoding.UTF8.GetBytes(sectionHeader.Name, 0, sectionHeader.Name.Length, name, 0); - bw.Write(name); - bw.Write(sectionHeader.VirtualSize); - bw.Write(sectionHeader.VirtualAddress); - bw.Write(sectionHeader.SizeOfRawData); - bw.Write(sectionHeader.PointerToRawData); - bw.Write(sectionHeader.PointerToRelocations); - bw.Write(sectionHeader.PointerToLinenumbers); - bw.Write(sectionHeader.NumberOfRelocations); - bw.Write(sectionHeader.NumberOfLinenumbers); - bw.Write(sectionHeader.Characteristics); - } - - internal uint ToFileAlignment(uint p) - { - return (p + (Headers.OptionalHeader.FileAlignment - 1)) & ~(Headers.OptionalHeader.FileAlignment - 1); - } - - internal uint ToSectionAlignment(uint p) - { - return (p + (Headers.OptionalHeader.SectionAlignment - 1)) & ~(Headers.OptionalHeader.SectionAlignment - 1); - } - } - - sealed class IMAGE_NT_HEADERS - { - public DWORD Signature = 0x00004550; // "PE\0\0" - public IMAGE_FILE_HEADER FileHeader = new IMAGE_FILE_HEADER(); - public IMAGE_OPTIONAL_HEADER OptionalHeader = new IMAGE_OPTIONAL_HEADER(); - } - - sealed class IMAGE_FILE_HEADER - { - public const WORD IMAGE_FILE_MACHINE_I386 = 0x014c; - public const WORD IMAGE_FILE_MACHINE_ARM = 0x01c4; - public const WORD IMAGE_FILE_MACHINE_IA64 = 0x0200; - public const WORD IMAGE_FILE_MACHINE_AMD64 = 0x8664; - - public const WORD IMAGE_FILE_32BIT_MACHINE = 0x0100; - public const WORD IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002; - public const WORD IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020; - public const WORD IMAGE_FILE_DLL = 0x2000; - - public WORD Machine; - public WORD NumberOfSections; - public DWORD TimeDateStamp = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; - public DWORD PointerToSymbolTable = 0; - public DWORD NumberOfSymbols = 0; - public WORD SizeOfOptionalHeader = 0xE0; - public WORD Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; - } - - sealed class IMAGE_OPTIONAL_HEADER - { - public const WORD IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b; - public const WORD IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b; - - public const WORD IMAGE_SUBSYSTEM_WINDOWS_GUI = 2; - public const WORD IMAGE_SUBSYSTEM_WINDOWS_CUI = 3; - - public WORD Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC; - public BYTE MajorLinkerVersion = 8; - public BYTE MinorLinkerVersion = 0; - public DWORD SizeOfCode; - public DWORD SizeOfInitializedData; - public DWORD SizeOfUninitializedData; - public DWORD AddressOfEntryPoint; - public DWORD BaseOfCode; - public DWORD BaseOfData; - public ULONGLONG ImageBase; - public DWORD SectionAlignment = 0x2000; - public DWORD FileAlignment; - public WORD MajorOperatingSystemVersion = 4; - public WORD MinorOperatingSystemVersion = 0; - public WORD MajorImageVersion = 0; - public WORD MinorImageVersion = 0; - public WORD MajorSubsystemVersion = 4; - public WORD MinorSubsystemVersion = 0; - public DWORD Win32VersionValue = 0; - public DWORD SizeOfImage; - public DWORD SizeOfHeaders; - public DWORD CheckSum = 0; - public WORD Subsystem; - public WORD DllCharacteristics; - public ULONGLONG SizeOfStackReserve; - public ULONGLONG SizeOfStackCommit = 0x1000; - public ULONGLONG SizeOfHeapReserve = 0x100000; - public ULONGLONG SizeOfHeapCommit = 0x1000; - public DWORD LoaderFlags = 0; - public DWORD NumberOfRvaAndSizes = 16; - public IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[16]; - - internal void Write(BinaryWriter bw) - { - bw.Write(Magic); - bw.Write(MajorLinkerVersion); - bw.Write(MinorLinkerVersion); - bw.Write(SizeOfCode); - bw.Write(SizeOfInitializedData); - bw.Write(SizeOfUninitializedData); - bw.Write(AddressOfEntryPoint); - bw.Write(BaseOfCode); - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - bw.Write(BaseOfData); - bw.Write((DWORD)ImageBase); - } - else - { - bw.Write(ImageBase); - } - bw.Write(SectionAlignment); - bw.Write(FileAlignment); - bw.Write(MajorOperatingSystemVersion); - bw.Write(MinorOperatingSystemVersion); - bw.Write(MajorImageVersion); - bw.Write(MinorImageVersion); - bw.Write(MajorSubsystemVersion); - bw.Write(MinorSubsystemVersion); - bw.Write(Win32VersionValue); - bw.Write(SizeOfImage); - bw.Write(SizeOfHeaders); - bw.Write(CheckSum); - bw.Write(Subsystem); - bw.Write(DllCharacteristics); - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - bw.Write((DWORD)SizeOfStackReserve); - } - else - { - bw.Write(SizeOfStackReserve); - } - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - bw.Write((DWORD)SizeOfStackCommit); - } - else - { - bw.Write(SizeOfStackCommit); - } - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - bw.Write((DWORD)SizeOfHeapReserve); - } - else - { - bw.Write(SizeOfHeapReserve); - } - if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) - { - bw.Write((DWORD)SizeOfHeapCommit); - } - else - { - bw.Write(SizeOfHeapCommit); - } - bw.Write(LoaderFlags); - bw.Write(NumberOfRvaAndSizes); - for (int i = 0; i < DataDirectory.Length; i++) - { - bw.Write(DataDirectory[i].VirtualAddress); - bw.Write(DataDirectory[i].Size); - } - } - } - - class SectionHeader - { - public const DWORD IMAGE_SCN_CNT_CODE = 0x00000020; - public const DWORD IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040; - public const DWORD IMAGE_SCN_MEM_DISCARDABLE = 0x02000000; - public const DWORD IMAGE_SCN_MEM_EXECUTE = 0x20000000; - public const DWORD IMAGE_SCN_MEM_READ = 0x40000000; - public const DWORD IMAGE_SCN_MEM_WRITE = 0x80000000; - - public string Name; // 8 byte UTF8 encoded 0-padded - public DWORD VirtualSize; - public DWORD VirtualAddress; - public DWORD SizeOfRawData; - public DWORD PointerToRawData; -#pragma warning disable 649 // the follow fields are never assigned to - public DWORD PointerToRelocations; - public DWORD PointerToLinenumbers; - public WORD NumberOfRelocations; - public WORD NumberOfLinenumbers; -#pragma warning restore 649 - public DWORD Characteristics; - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/ResourceSection.cs b/mcs/class/IKVM.Reflection/Writer/ResourceSection.cs deleted file mode 100644 index 3789ca2c99d..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/ResourceSection.cs +++ /dev/null @@ -1,411 +0,0 @@ -/* - Copyright (C) 2010-2012 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using IKVM.Reflection.Reader; - -namespace IKVM.Reflection.Writer -{ - sealed class ResourceSection - { - private const int RT_ICON = 3; - private const int RT_GROUP_ICON = 14; - private const int RT_VERSION = 16; - private const int RT_MANIFEST = 24; - private ResourceDirectoryEntry root = new ResourceDirectoryEntry(new OrdinalOrName("root")); - private ByteBuffer bb; - private List linkOffsets; - - internal void AddVersionInfo(ByteBuffer versionInfo) - { - root[new OrdinalOrName(RT_VERSION)][new OrdinalOrName(1)][new OrdinalOrName(0)].Data = versionInfo; - } - - internal void AddIcon(byte[] iconFile) - { - BinaryReader br = new BinaryReader(new MemoryStream(iconFile)); - ushort idReserved = br.ReadUInt16(); - ushort idType = br.ReadUInt16(); - ushort idCount = br.ReadUInt16(); - if (idReserved != 0 || idType != 1) - { - throw new ArgumentException("The supplied byte array is not a valid .ico file."); - } - ByteBuffer group = new ByteBuffer(6 + 14 * idCount); - group.Write(idReserved); - group.Write(idType); - group.Write(idCount); - for (int i = 0; i < idCount; i++) - { - byte bWidth = br.ReadByte(); - byte bHeight = br.ReadByte(); - byte bColorCount = br.ReadByte(); - byte bReserved = br.ReadByte(); - ushort wPlanes = br.ReadUInt16(); - ushort wBitCount = br.ReadUInt16(); - uint dwBytesInRes = br.ReadUInt32(); - uint dwImageOffset = br.ReadUInt32(); - - // we start the icon IDs at 2 - ushort id = (ushort)(2 + i); - - group.Write(bWidth); - group.Write(bHeight); - group.Write(bColorCount); - group.Write(bReserved); - group.Write(wPlanes); - group.Write(wBitCount); - group.Write(dwBytesInRes); - group.Write(id); - - byte[] icon = new byte[dwBytesInRes]; - Buffer.BlockCopy(iconFile, (int)dwImageOffset, icon, 0, icon.Length); - root[new OrdinalOrName(RT_ICON)][new OrdinalOrName(id)][new OrdinalOrName(0)].Data = ByteBuffer.Wrap(icon); - } - root[new OrdinalOrName(RT_GROUP_ICON)][new OrdinalOrName(32512)][new OrdinalOrName(0)].Data = group; - } - - internal void AddManifest(byte[] manifest, ushort resourceID) - { - root[new OrdinalOrName(RT_MANIFEST)][new OrdinalOrName(resourceID)][new OrdinalOrName(0)].Data = ByteBuffer.Wrap(manifest); - } - - internal void ExtractResources(byte[] buf) - { - ByteReader br = new ByteReader(buf, 0, buf.Length); - while (br.Length >= 32) - { - br.Align(4); - RESOURCEHEADER hdr = new RESOURCEHEADER(br); - if (hdr.DataSize != 0) - { - root[hdr.TYPE][hdr.NAME][new OrdinalOrName(hdr.LanguageId)].Data = ByteBuffer.Wrap(br.ReadBytes(hdr.DataSize)); - } - } - } - - internal void Finish() - { - if (bb != null) - { - throw new InvalidOperationException(); - } - bb = new ByteBuffer(1024); - linkOffsets = new List(); - root.Write(bb, linkOffsets); - root = null; - } - - internal int Length - { - get { return bb.Length; } - } - - internal void Write(MetadataWriter mw, uint rva) - { - foreach (int offset in linkOffsets) - { - bb.Position = offset; - bb.Write(bb.GetInt32AtCurrentPosition() + (int)rva); - } - mw.Write(bb); - } - } - - sealed class ResourceDirectoryEntry - { - internal readonly OrdinalOrName OrdinalOrName; - internal ByteBuffer Data; - private int namedEntries; - private readonly List entries = new List(); - - internal ResourceDirectoryEntry(OrdinalOrName id) - { - this.OrdinalOrName = id; - } - - internal ResourceDirectoryEntry this[OrdinalOrName id] - { - get - { - foreach (ResourceDirectoryEntry entry in entries) - { - if (entry.OrdinalOrName.IsEqual(id)) - { - return entry; - } - } - // the entries must be sorted - ResourceDirectoryEntry newEntry = new ResourceDirectoryEntry(id); - if (id.Name == null) - { - for (int i = namedEntries; i < entries.Count; i++) - { - if (entries[i].OrdinalOrName.IsGreaterThan(id)) - { - entries.Insert(i, newEntry); - return newEntry; - } - } - entries.Add(newEntry); - return newEntry; - } - else - { - for (int i = 0; i < namedEntries; i++) - { - if (entries[i].OrdinalOrName.IsGreaterThan(id)) - { - entries.Insert(i, newEntry); - namedEntries++; - return newEntry; - } - } - entries.Insert(namedEntries++, newEntry); - return newEntry; - } - } - } - - private int DirectoryLength - { - get - { - if (Data != null) - { - return 16; - } - else - { - int length = 16 + entries.Count * 8; - foreach (ResourceDirectoryEntry entry in entries) - { - length += entry.DirectoryLength; - } - return length; - } - } - } - - internal void Write(ByteBuffer bb, List linkOffsets) - { - if (entries.Count != 0) - { - int stringTableOffset = this.DirectoryLength; - Dictionary strings = new Dictionary(); - ByteBuffer stringTable = new ByteBuffer(16); - int offset = 16 + entries.Count * 8; - for (int pass = 0; pass < 3; pass++) - { - Write(bb, pass, 0, ref offset, strings, ref stringTableOffset, stringTable); - } - // the pecoff spec says that the string table is between the directory entries and the data entries, - // but the windows linker puts them after the data entries, so we do too. - stringTable.Align(4); - offset += stringTable.Length; - WriteResourceDataEntries(bb, linkOffsets, ref offset); - bb.Write(stringTable); - WriteData(bb); - } - } - - private void WriteResourceDataEntries(ByteBuffer bb, List linkOffsets, ref int offset) - { - foreach (ResourceDirectoryEntry entry in entries) - { - if (entry.Data != null) - { - linkOffsets.Add(bb.Position); - bb.Write(offset); - bb.Write(entry.Data.Length); - bb.Write(0); // code page - bb.Write(0); // reserved - offset += (entry.Data.Length + 3) & ~3; - } - else - { - entry.WriteResourceDataEntries(bb, linkOffsets, ref offset); - } - } - } - - private void WriteData(ByteBuffer bb) - { - foreach (ResourceDirectoryEntry entry in entries) - { - if (entry.Data != null) - { - bb.Write(entry.Data); - bb.Align(4); - } - else - { - entry.WriteData(bb); - } - } - } - - private void Write(ByteBuffer bb, int writeDepth, int currentDepth, ref int offset, Dictionary strings, ref int stringTableOffset, ByteBuffer stringTable) - { - if (currentDepth == writeDepth) - { - // directory header - bb.Write(0); // Characteristics - bb.Write(0); // Time/Date Stamp - bb.Write(0); // Version (Major / Minor) - bb.Write((ushort)namedEntries); - bb.Write((ushort)(entries.Count - namedEntries)); - } - foreach (ResourceDirectoryEntry entry in entries) - { - if (currentDepth == writeDepth) - { - entry.WriteEntry(bb, ref offset, strings, ref stringTableOffset, stringTable); - } - else - { - entry.Write(bb, writeDepth, currentDepth + 1, ref offset, strings, ref stringTableOffset, stringTable); - } - } - } - - private void WriteEntry(ByteBuffer bb, ref int offset, Dictionary strings, ref int stringTableOffset, ByteBuffer stringTable) - { - WriteNameOrOrdinal(bb, OrdinalOrName, strings, ref stringTableOffset, stringTable); - if (Data == null) - { - bb.Write(0x80000000U | (uint)offset); - } - else - { - bb.Write(offset); - } - offset += 16 + entries.Count * 8; - } - - private static void WriteNameOrOrdinal(ByteBuffer bb, OrdinalOrName id, Dictionary strings, ref int stringTableOffset, ByteBuffer stringTable) - { - if (id.Name == null) - { - bb.Write((int)id.Ordinal); - } - else - { - int stringOffset; - if (!strings.TryGetValue(id.Name, out stringOffset)) - { - stringOffset = stringTableOffset; - strings.Add(id.Name, stringOffset); - stringTableOffset += id.Name.Length * 2 + 2; - stringTable.Write((ushort)id.Name.Length); - foreach (char c in id.Name) - { - stringTable.Write((short)c); - } - } - bb.Write(0x80000000U | (uint)stringOffset); - } - } - } - - struct OrdinalOrName - { - internal readonly ushort Ordinal; - internal readonly string Name; - - internal OrdinalOrName(ushort value) - { - Ordinal = value; - Name = null; - } - - internal OrdinalOrName(string value) - { - Ordinal = 0xFFFF; - Name = value; - } - - internal bool IsGreaterThan(OrdinalOrName other) - { - return this.Name == null - ? this.Ordinal > other.Ordinal - : String.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase) > 0; - } - - internal bool IsEqual(OrdinalOrName other) - { - return this.Name == null - ? this.Ordinal == other.Ordinal - : String.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase) == 0; - } - } - - struct RESOURCEHEADER - { - internal int DataSize; - internal int HeaderSize; - internal OrdinalOrName TYPE; - internal OrdinalOrName NAME; - internal int DataVersion; - internal ushort MemoryFlags; - internal ushort LanguageId; - internal int Version; - internal int Characteristics; - - internal RESOURCEHEADER(ByteReader br) - { - DataSize = br.ReadInt32(); - HeaderSize = br.ReadInt32(); - TYPE = ReadOrdinalOrName(br); - NAME = ReadOrdinalOrName(br); - br.Align(4); - DataVersion = br.ReadInt32(); - MemoryFlags = br.ReadUInt16(); - LanguageId = br.ReadUInt16(); - Version = br.ReadInt32(); - Characteristics = br.ReadInt32(); - } - - private static OrdinalOrName ReadOrdinalOrName(ByteReader br) - { - char c = br.ReadChar(); - if (c == 0xFFFF) - { - return new OrdinalOrName(br.ReadUInt16()); - } - else - { - StringBuilder sb = new StringBuilder(); - while (c != 0) - { - sb.Append(c); - c = br.ReadChar(); - } - return new OrdinalOrName(sb.ToString()); - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/TextSection.cs b/mcs/class/IKVM.Reflection/Writer/TextSection.cs deleted file mode 100644 index a8b4785ef59..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/TextSection.cs +++ /dev/null @@ -1,855 +0,0 @@ -/* - Copyright (C) 2008-2011 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Diagnostics; -using System.IO; -using System.Collections.Generic; -using System.Text; -using IKVM.Reflection.Emit; -using IKVM.Reflection.Impl; -using IKVM.Reflection.Metadata; - -namespace IKVM.Reflection.Writer -{ - sealed class TextSection - { - private readonly PEWriter peWriter; - private readonly CliHeader cliHeader; - private readonly ModuleBuilder moduleBuilder; - private readonly uint strongNameSignatureLength; - private readonly ExportTables exportTables; - - internal TextSection(PEWriter peWriter, CliHeader cliHeader, ModuleBuilder moduleBuilder, int strongNameSignatureLength) - { - this.peWriter = peWriter; - this.cliHeader = cliHeader; - this.moduleBuilder = moduleBuilder; - this.strongNameSignatureLength = (uint)strongNameSignatureLength; - if (moduleBuilder.unmanagedExports.Count != 0) - { - this.exportTables = new ExportTables(this); - } - } - - internal uint PointerToRawData - { - get { return peWriter.ToFileAlignment(peWriter.HeaderSize); } - } - - internal uint BaseRVA - { - get { return 0x2000; } - } - - internal uint ImportAddressTableRVA - { - get { return BaseRVA; } - } - - internal uint ImportAddressTableLength - { - get - { - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - return 8; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: - return 0; - default: - return 16; - } - } - } - - internal uint ComDescriptorRVA - { - get { return ImportAddressTableRVA + ImportAddressTableLength; } - } - - internal uint ComDescriptorLength - { - get { return cliHeader.Cb; } - } - - internal uint MethodBodiesRVA - { - get { return (ComDescriptorRVA + ComDescriptorLength + 7) & ~7U; } - } - - private uint MethodBodiesLength - { - get { return (uint)moduleBuilder.methodBodies.Length; } - } - - private uint ResourcesRVA - { - get - { - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: - return (MethodBodiesRVA + MethodBodiesLength + 3) & ~3U; - default: - return (MethodBodiesRVA + MethodBodiesLength + 15) & ~15U; - } - } - } - - private uint ResourcesLength - { - get { return (uint)moduleBuilder.manifestResources.Length; } - } - - internal uint StrongNameSignatureRVA - { - get - { - return (ResourcesRVA + ResourcesLength + 3) & ~3U; - } - } - - internal uint StrongNameSignatureLength - { - get - { - return strongNameSignatureLength; - } - } - - private uint MetadataRVA - { - get - { - return (StrongNameSignatureRVA + StrongNameSignatureLength + 3) & ~3U; - } - } - - private uint MetadataLength - { - get { return (uint)moduleBuilder.MetadataLength; } - } - - private uint VTableFixupsRVA - { - get { return (MetadataRVA + MetadataLength + 7) & ~7U; } - } - - private uint VTableFixupsLength - { - get { return (uint)moduleBuilder.vtablefixups.Count * 8; } - } - - internal uint DebugDirectoryRVA - { - get { return VTableFixupsRVA + VTableFixupsLength; } - } - - internal uint DebugDirectoryLength - { - get - { - if (DebugDirectoryContentsLength != 0) - { - return 28; - } - return 0; - } - } - - private uint DebugDirectoryContentsLength - { - get - { - if (moduleBuilder.symbolWriter != null) - { - IMAGE_DEBUG_DIRECTORY idd = new IMAGE_DEBUG_DIRECTORY(); - return (uint)SymbolSupport.GetDebugInfo(moduleBuilder.symbolWriter, ref idd).Length; - } - return 0; - } - } - - internal uint ExportDirectoryRVA - { - get { return (DebugDirectoryRVA + DebugDirectoryLength + DebugDirectoryContentsLength + 15) & ~15U; } - } - - internal uint ExportDirectoryLength - { - get { return moduleBuilder.unmanagedExports.Count == 0 ? 0U : 40U; } - } - - private uint ExportTablesRVA - { - get { return ExportDirectoryRVA + ExportDirectoryLength; } - } - - private uint ExportTablesLength - { - get { return exportTables == null ? 0U : exportTables.Length; } - } - - internal uint ImportDirectoryRVA - { - // on AMD64 (and probably IA64) the import directory needs to be 16 byte aligned (on I386 4 byte alignment is sufficient) - get { return (ExportTablesRVA + ExportTablesLength + 15) & ~15U; } - } - - internal uint ImportDirectoryLength - { - get - { - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: - return 0; - default: - return (ImportHintNameTableRVA - ImportDirectoryRVA) + 27; - } - } - } - - private uint ImportHintNameTableRVA - { - get - { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) - { - return (ImportDirectoryRVA + 48 + 15) & ~15U; - } - else - { - return (ImportDirectoryRVA + 48 + 4 + 15) & ~15U; - } - } - } - - internal uint StartupStubRVA - { - get - { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64) - { - // note that the alignment is driven by the requirement that the two relocation fixups are in a single page - return (ImportDirectoryRVA + ImportDirectoryLength + 15U) & ~15U; - } - else - { - // the additional 2 bytes padding are to align the address in the jump (which is a relocation fixup) - return 2 + ((ImportDirectoryRVA + ImportDirectoryLength + 3U) & ~3U); - } - } - } - - internal uint StartupStubLength - { - get - { - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - return 6; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: - return 12; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64: - return 48; - default: - return 0; - } - } - } - - private void WriteRVA(MetadataWriter mw, uint rva) - { - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: - mw.Write(rva); - break; - default: - mw.Write((ulong)rva); - break; - } - } - - internal void Write(MetadataWriter mw, uint sdataRVA) - { - // Now that we're ready to start writing, we need to do some fix ups - moduleBuilder.TypeRef.Fixup(moduleBuilder); - moduleBuilder.MethodDef.Fixup(this); - moduleBuilder.MethodImpl.Fixup(moduleBuilder); - moduleBuilder.MethodSemantics.Fixup(moduleBuilder); - moduleBuilder.InterfaceImpl.Fixup(); - moduleBuilder.ResolveInterfaceImplPseudoTokens(); - moduleBuilder.MemberRef.Fixup(moduleBuilder); - moduleBuilder.Constant.Fixup(moduleBuilder); - moduleBuilder.FieldMarshal.Fixup(moduleBuilder); - moduleBuilder.DeclSecurity.Fixup(moduleBuilder); - moduleBuilder.GenericParam.Fixup(moduleBuilder); - moduleBuilder.CustomAttribute.Fixup(moduleBuilder); - moduleBuilder.FieldLayout.Fixup(moduleBuilder); - moduleBuilder.FieldRVA.Fixup(moduleBuilder, (int)sdataRVA, (int)this.MethodBodiesRVA); - moduleBuilder.ImplMap.Fixup(moduleBuilder); - moduleBuilder.ExportedType.Fixup(moduleBuilder); - moduleBuilder.ManifestResource.Fixup(moduleBuilder); - moduleBuilder.MethodSpec.Fixup(moduleBuilder); - moduleBuilder.GenericParamConstraint.Fixup(moduleBuilder); - - // Import Address Table - AssertRVA(mw, ImportAddressTableRVA); - if (ImportAddressTableLength != 0) - { - WriteRVA(mw, ImportHintNameTableRVA); - WriteRVA(mw, 0); - } - - // CLI Header - AssertRVA(mw, ComDescriptorRVA); - cliHeader.MetaData.VirtualAddress = MetadataRVA; - cliHeader.MetaData.Size = MetadataLength; - if (ResourcesLength != 0) - { - cliHeader.Resources.VirtualAddress = ResourcesRVA; - cliHeader.Resources.Size = ResourcesLength; - } - if (StrongNameSignatureLength != 0) - { - cliHeader.StrongNameSignature.VirtualAddress = StrongNameSignatureRVA; - cliHeader.StrongNameSignature.Size = StrongNameSignatureLength; - } - if (VTableFixupsLength != 0) - { - cliHeader.VTableFixups.VirtualAddress = VTableFixupsRVA; - cliHeader.VTableFixups.Size = VTableFixupsLength; - } - cliHeader.Write(mw); - - // alignment padding - for (int i = (int)(MethodBodiesRVA - (ComDescriptorRVA + ComDescriptorLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Method Bodies - mw.Write(moduleBuilder.methodBodies); - - // alignment padding - for (int i = (int)(ResourcesRVA - (MethodBodiesRVA + MethodBodiesLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Resources - mw.Write(moduleBuilder.manifestResources); - - // The strong name signature live here (if it exists), but it will written later - // and the following alignment padding will take care of reserving the space. - - // alignment padding - for (int i = (int)(MetadataRVA - (ResourcesRVA + ResourcesLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Metadata - AssertRVA(mw, MetadataRVA); - moduleBuilder.WriteMetadata(mw); - - // alignment padding - for (int i = (int)(VTableFixupsRVA - (MetadataRVA + MetadataLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // VTableFixups - AssertRVA(mw, VTableFixupsRVA); - WriteVTableFixups(mw, sdataRVA); - - // Debug Directory - AssertRVA(mw, DebugDirectoryRVA); - WriteDebugDirectory(mw); - - // alignment padding - for (int i = (int)(ExportDirectoryRVA - (DebugDirectoryRVA + DebugDirectoryLength + DebugDirectoryContentsLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Export Directory - AssertRVA(mw, ExportDirectoryRVA); - WriteExportDirectory(mw); - - // Export Tables - AssertRVA(mw, ExportTablesRVA); - WriteExportTables(mw, sdataRVA); - - // alignment padding - for (int i = (int)(ImportDirectoryRVA - (ExportTablesRVA + ExportTablesLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Import Directory - AssertRVA(mw, ImportDirectoryRVA); - if (ImportDirectoryLength != 0) - { - WriteImportDirectory(mw); - } - - // alignment padding - for (int i = (int)(StartupStubRVA - (ImportDirectoryRVA + ImportDirectoryLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Startup Stub - AssertRVA(mw, StartupStubRVA); - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64) - { - /* - * 48 A1 00 20 40 00 00 00 00 00 mov rax,qword ptr [0000000000402000h] - * FF E0 jmp rax - */ - mw.Write((ushort)0xA148); - mw.Write(peWriter.Headers.OptionalHeader.ImageBase + ImportAddressTableRVA); - mw.Write((ushort)0xE0FF); - } - else if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64) - { - mw.Write(new byte[] { - 0x0B, 0x48, 0x00, 0x02, 0x18, 0x10, 0xA0, 0x40, 0x24, 0x30, 0x28, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x10, 0x08, 0x00, 0x12, 0x18, 0x10, 0x60, 0x50, 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00 - }); - mw.Write(peWriter.Headers.OptionalHeader.ImageBase + StartupStubRVA); - mw.Write(peWriter.Headers.OptionalHeader.ImageBase + BaseRVA); - } - else if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) - { - mw.Write((ushort)0x25FF); - mw.Write((uint)peWriter.Headers.OptionalHeader.ImageBase + ImportAddressTableRVA); - } - } - - [Conditional("DEBUG")] - private void AssertRVA(MetadataWriter mw, uint rva) - { - Debug.Assert(mw.Position - PointerToRawData + BaseRVA == rva); - } - - private void WriteVTableFixups(MetadataWriter mw, uint sdataRVA) - { - foreach (ModuleBuilder.VTableFixups fixups in moduleBuilder.vtablefixups) - { - mw.Write(fixups.initializedDataOffset + sdataRVA); - mw.Write(fixups.count); - mw.Write(fixups.type); - } - } - - private void WriteDebugDirectory(MetadataWriter mw) - { - if (DebugDirectoryLength != 0) - { - IMAGE_DEBUG_DIRECTORY idd = new IMAGE_DEBUG_DIRECTORY(); - idd.Characteristics = 0; - idd.TimeDateStamp = peWriter.Headers.FileHeader.TimeDateStamp; - byte[] buf = SymbolSupport.GetDebugInfo(moduleBuilder.symbolWriter, ref idd); - idd.PointerToRawData = (DebugDirectoryRVA - BaseRVA) + DebugDirectoryLength + PointerToRawData; - idd.AddressOfRawData = DebugDirectoryRVA + DebugDirectoryLength; - mw.Write(idd.Characteristics); - mw.Write(idd.TimeDateStamp); - mw.Write(idd.MajorVersion); - mw.Write(idd.MinorVersion); - mw.Write(idd.Type); - mw.Write(idd.SizeOfData); - mw.Write(idd.AddressOfRawData); - mw.Write(idd.PointerToRawData); - mw.Write(buf); - } - } - - private sealed class ExportTables - { - private readonly TextSection text; - internal readonly uint entries; - internal readonly uint ordinalBase; - internal readonly uint nameCount; - internal readonly uint namesLength; - internal readonly uint exportAddressTableRVA; - internal readonly uint exportNamePointerTableRVA; - internal readonly uint exportOrdinalTableRVA; - internal readonly uint namesRVA; - internal readonly uint stubsRVA; - private readonly uint stubLength; - - internal ExportTables(TextSection text) - { - this.text = text; - ordinalBase = GetOrdinalBase(out entries); - namesLength = GetExportNamesLength(out nameCount); - exportAddressTableRVA = text.ExportTablesRVA; - exportNamePointerTableRVA = exportAddressTableRVA + 4 * entries; - exportOrdinalTableRVA = exportNamePointerTableRVA + 4 * nameCount; - namesRVA = exportOrdinalTableRVA + 2 * nameCount; - stubsRVA = (namesRVA + namesLength + 15) & ~15U; - // note that we align the stubs to avoid having to deal with the relocation crossing a page boundary - switch (text.peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - stubLength = 8; - break; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: - stubLength = 16; - break; - default: - throw new NotImplementedException(); - } - } - - internal uint Length - { - get { return (stubsRVA + stubLength * (uint)text.moduleBuilder.unmanagedExports.Count) - text.ExportTablesRVA; } - } - - private uint GetOrdinalBase(out uint entries) - { - uint min = uint.MaxValue; - uint max = uint.MinValue; - foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) - { - uint ordinal = (uint)exp.ordinal; - min = Math.Min(min, ordinal); - max = Math.Max(max, ordinal); - } - entries = 1 + (max - min); - return min; - } - - private uint GetExportNamesLength(out uint nameCount) - { - nameCount = 0; - // the first name in the names list is the module name (the Export Directory contains a name of the current module) - uint length = (uint)text.moduleBuilder.fileName.Length + 1; - foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) - { - if (exp.name != null) - { - nameCount++; - length += (uint)exp.name.Length + 1; - } - } - return length; - } - - internal void Write(MetadataWriter mw, uint sdataRVA) - { - // sort the exports by ordinal - text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportOrdinals); - - // Now write the Export Address Table - text.AssertRVA(mw, exportAddressTableRVA); - for (int i = 0, pos = 0; i < entries; i++) - { - if (text.moduleBuilder.unmanagedExports[pos].ordinal == i + ordinalBase) - { - mw.Write(stubsRVA + (uint)pos * stubLength); - pos++; - } - else - { - mw.Write(0); - } - } - - // sort the exports by name - text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportNames); - - // Now write the Export Name Pointer Table - text.AssertRVA(mw, exportNamePointerTableRVA); - uint nameOffset = (uint)text.moduleBuilder.fileName.Length + 1; - foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) - { - if (exp.name != null) - { - mw.Write(namesRVA + nameOffset); - nameOffset += (uint)exp.name.Length + 1; - } - } - - // Now write the Export Ordinal Table - text.AssertRVA(mw, exportOrdinalTableRVA); - foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) - { - if (exp.name != null) - { - mw.Write((ushort)(exp.ordinal - ordinalBase)); - } - } - - // Now write the actual names - text.AssertRVA(mw, namesRVA); - mw.Write(Encoding.ASCII.GetBytes(text.moduleBuilder.fileName)); - mw.Write((byte)0); - foreach (UnmanagedExport exp in text.moduleBuilder.unmanagedExports) - { - if (exp.name != null) - { - mw.Write(Encoding.ASCII.GetBytes(exp.name)); - mw.Write((byte)0); - } - } - text.AssertRVA(mw, namesRVA + namesLength); - - // alignment padding - for (int i = (int)(stubsRVA - (namesRVA + namesLength)); i > 0; i--) - { - mw.Write((byte)0); - } - - // sort the exports by ordinal - text.moduleBuilder.unmanagedExports.Sort(CompareUnmanagedExportOrdinals); - - // Now write the stubs - text.AssertRVA(mw, stubsRVA); - - for (int i = 0, pos = 0; i < entries; i++) - { - if (text.moduleBuilder.unmanagedExports[pos].ordinal == i + ordinalBase) - { - switch (text.peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - mw.Write((byte)0xFF); - mw.Write((byte)0x25); - mw.Write((uint)text.peWriter.Headers.OptionalHeader.ImageBase + text.moduleBuilder.unmanagedExports[pos].rva.initializedDataOffset + sdataRVA); - mw.Write((short)0); // alignment - break; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: - mw.Write((byte)0x48); - mw.Write((byte)0xA1); - mw.Write(text.peWriter.Headers.OptionalHeader.ImageBase + text.moduleBuilder.unmanagedExports[pos].rva.initializedDataOffset + sdataRVA); - mw.Write((byte)0xFF); - mw.Write((byte)0xE0); - mw.Write(0); // alignment - break; - default: - throw new NotImplementedException(); - } - pos++; - } - } - } - - private static int CompareUnmanagedExportNames(UnmanagedExport x, UnmanagedExport y) - { - if (x.name == null) - { - return y.name == null ? 0 : 1; - } - if (y.name == null) - { - return -1; - } - return x.name.CompareTo(y.name); - } - - private static int CompareUnmanagedExportOrdinals(UnmanagedExport x, UnmanagedExport y) - { - return x.ordinal.CompareTo(y.ordinal); - } - - internal void WriteRelocations(MetadataWriter mw) - { - // we assume that unmanagedExports is still sorted by ordinal - for (int i = 0, pos = 0; i < entries; i++) - { - if (text.moduleBuilder.unmanagedExports[pos].ordinal == i + ordinalBase) - { - // both I386 and AMD64 have the address at offset 2 - text.WriteRelocationBlock(mw, stubsRVA + 2 + (uint)pos * stubLength); - pos++; - } - } - } - } - - private uint GetOrdinalBase(out uint entries) - { - uint min = uint.MaxValue; - uint max = uint.MinValue; - foreach (UnmanagedExport exp in moduleBuilder.unmanagedExports) - { - uint ordinal = (uint)exp.ordinal; - min = Math.Min(min, ordinal); - max = Math.Max(max, ordinal); - } - entries = 1 + (max - min); - return min; - } - - private uint GetExportNamesLength(out uint nameCount) - { - nameCount = 0; - uint length = 0; - foreach (UnmanagedExport exp in moduleBuilder.unmanagedExports) - { - if (exp.name != null) - { - nameCount++; - length += (uint)exp.name.Length + 1; - } - } - return length; - } - - private void WriteExportDirectory(MetadataWriter mw) - { - if (ExportDirectoryLength != 0) - { - // Flags - mw.Write(0); - // Date/Time Stamp - mw.Write(peWriter.Headers.FileHeader.TimeDateStamp); - // Major Version - mw.Write((short)0); - // Minor Version - mw.Write((short)0); - // Name RVA - mw.Write(exportTables.namesRVA); - // Ordinal Base - mw.Write(exportTables.ordinalBase); - // Address Table Entries - mw.Write(exportTables.entries); - // Number of Name Pointers - mw.Write(exportTables.nameCount); - // Export Address Table RVA - mw.Write(exportTables.exportAddressTableRVA); - // Name Pointer RVA - mw.Write(exportTables.exportNamePointerTableRVA); - // Ordinal Table RVA - mw.Write(exportTables.exportOrdinalTableRVA); - } - } - - private void WriteExportTables(MetadataWriter mw, uint sdataRVA) - { - if (exportTables != null) - { - exportTables.Write(mw, sdataRVA); - } - } - - private void WriteImportDirectory(MetadataWriter mw) - { - mw.Write(ImportDirectoryRVA + 40); // ImportLookupTable - mw.Write(0); // DateTimeStamp - mw.Write(0); // ForwarderChain - mw.Write(ImportHintNameTableRVA + 14); // Name - mw.Write(ImportAddressTableRVA); - mw.Write(new byte[20]); - // Import Lookup Table - mw.Write(ImportHintNameTableRVA); // Hint/Name Table RVA - int size = 48; - if (peWriter.Headers.FileHeader.Machine != IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) - { - size += 4; - mw.Write(0); - } - mw.Write(0); - - // alignment padding - for (int i = (int)(ImportHintNameTableRVA - (ImportDirectoryRVA + size)); i > 0; i--) - { - mw.Write((byte)0); - } - - // Hint/Name Table - AssertRVA(mw, ImportHintNameTableRVA); - mw.Write((ushort)0); // Hint - if ((peWriter.Headers.FileHeader.Characteristics & IMAGE_FILE_HEADER.IMAGE_FILE_DLL) != 0) - { - mw.Write(System.Text.Encoding.ASCII.GetBytes("_CorDllMain")); - } - else - { - mw.Write(System.Text.Encoding.ASCII.GetBytes("_CorExeMain")); - } - mw.Write((byte)0); - // Name - mw.Write(System.Text.Encoding.ASCII.GetBytes("mscoree.dll")); - mw.Write((ushort)0); - } - - internal int Length - { - get { return (int)(StartupStubRVA - BaseRVA + StartupStubLength); } - } - - internal void WriteRelocations(MetadataWriter mw) - { - uint relocAddress = this.StartupStubRVA; - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: - relocAddress += 2; - break; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64: - relocAddress += 0x20; - break; - } - WriteRelocationBlock(mw, relocAddress); - if (exportTables != null) - { - exportTables.WriteRelocations(mw); - } - } - - // note that we're lazy and write a new relocation block for every relocation - // even if they are in the same page (since there is typically only one anyway) - private void WriteRelocationBlock(MetadataWriter mw, uint relocAddress) - { - uint pageRVA = relocAddress & ~0xFFFU; - mw.Write(pageRVA); // PageRVA - mw.Write(0x000C); // Block Size - switch (peWriter.Headers.FileHeader.Machine) - { - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: - mw.Write(0x3000 + relocAddress - pageRVA); // Type / Offset - break; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: - mw.Write(0xA000 + relocAddress - pageRVA); // Type / Offset - break; - case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64: - // on IA64 the StartupStubRVA is 16 byte aligned, so these two addresses won't cross a page boundary - mw.Write((short)(0xA000 + relocAddress - pageRVA)); // Type / Offset - mw.Write((short)(0xA000 + relocAddress - pageRVA + 8)); // Type / Offset - break; - } - } - } -} diff --git a/mcs/class/IKVM.Reflection/Writer/VersionInfo.cs b/mcs/class/IKVM.Reflection/Writer/VersionInfo.cs deleted file mode 100644 index 4c76b4964e8..00000000000 --- a/mcs/class/IKVM.Reflection/Writer/VersionInfo.cs +++ /dev/null @@ -1,278 +0,0 @@ -/* - Copyright (C) 2008 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Globalization; -using IKVM.Reflection.Emit; - -namespace IKVM.Reflection.Writer -{ - sealed class VersionInfo - { - private AssemblyName name; - private string fileName; - internal string copyright; - internal string trademark; - internal string product; - internal string company; - private string description; - private string title; - internal string informationalVersion; - private string fileVersion; - - internal void SetName(AssemblyName name) - { - this.name = name; - } - - internal void SetFileName(string assemblyFileName) - { - this.fileName = assemblyFileName; - } - - internal void SetAttribute(CustomAttributeBuilder cab) - { - Universe u = cab.Constructor.Module.universe; - Type type = cab.Constructor.DeclaringType; - if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute) - { - copyright = (string)cab.GetConstructorArgument(0); - } - else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute) - { - trademark = (string)cab.GetConstructorArgument(0); - } - else if (product == null && type == u.System_Reflection_AssemblyProductAttribute) - { - product = (string)cab.GetConstructorArgument(0); - } - else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute) - { - company = (string)cab.GetConstructorArgument(0); - } - else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute) - { - description = (string)cab.GetConstructorArgument(0); - } - else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute) - { - title = (string)cab.GetConstructorArgument(0); - } - else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute) - { - informationalVersion = (string)cab.GetConstructorArgument(0); - } - else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute) - { - fileVersion = (string)cab.GetConstructorArgument(0); - } - } - - internal void Write(ByteBuffer bb) - { - if (fileVersion == null) - { - if (name.Version != null) - { - fileVersion = name.Version.ToString(); - } - else - { - fileVersion = "0.0.0.0"; - } - } - - int codepage = 1200; // Unicode codepage - int lcid = 0x7f; - try - { - if (name.CultureInfo != null) - { - lcid = name.CultureInfo.LCID; - } - } - catch (ArgumentException) - { - // AssemblyName.CultureInfo throws an ArgumentException if AssemblyBuilder.__SetAssemblyCulture() was used to specify a non-existing culture - } - - Version filever = ParseVersionRobust(fileVersion); - int fileVersionMajor = filever.Major; - int fileVersionMinor = filever.Minor; - int fileVersionBuild = filever.Build; - int fileVersionRevision = filever.Revision; - - int productVersionMajor = fileVersionMajor; - int productVersionMinor = fileVersionMinor; - int productVersionBuild = fileVersionBuild; - int productVersionRevision = fileVersionRevision; - if (informationalVersion != null) - { - Version productver = ParseVersionRobust(informationalVersion); - productVersionMajor = productver.Major; - productVersionMinor = productver.Minor; - productVersionBuild = productver.Build; - productVersionRevision = productver.Revision; - } - - ByteBuffer stringTable = new ByteBuffer(512); - stringTable.Write((short)0); // wLength (placeholder) - stringTable.Write((short)0); // wValueLength - stringTable.Write((short)1); // wType - WriteUTF16Z(stringTable, string.Format("{0:x4}{1:x4}", lcid, codepage)); - stringTable.Align(4); - - WriteString(stringTable, "Comments", description); - WriteString(stringTable, "CompanyName", company); - WriteString(stringTable, "FileDescription", title); - WriteString(stringTable, "FileVersion", fileVersion); - WriteString(stringTable, "InternalName", name.Name); - WriteString(stringTable, "LegalCopyright", copyright); - WriteString(stringTable, "LegalTrademarks", trademark); - WriteString(stringTable, "OriginalFilename", fileName); - WriteString(stringTable, "ProductName", product); - WriteString(stringTable, "ProductVersion", informationalVersion); - - stringTable.Position = 0; - stringTable.Write((short)stringTable.Length); - - ByteBuffer stringFileInfo = new ByteBuffer(512); - stringFileInfo.Write((short)0); // wLength (placeholder) - stringFileInfo.Write((short)0); // wValueLength - stringFileInfo.Write((short)1); // wType - WriteUTF16Z(stringFileInfo, "StringFileInfo"); - stringFileInfo.Align(4); - stringFileInfo.Write(stringTable); - stringFileInfo.Position = 0; - stringFileInfo.Write((short)stringFileInfo.Length); - - byte[] preamble1 = new byte[] { - // VS_VERSIONINFO (platform SDK) - 0x34, 0x00, // wValueLength - 0x00, 0x00, // wType - 0x56, 0x00, 0x53, 0x00, 0x5F, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4F, 0x00, 0x4E, 0x00, 0x5F, 0x00, 0x49, 0x00, 0x4E, 0x00, 0x46, 0x00, 0x4F, 0x00, 0x00, 0x00, // "VS_VERSION_INFO\0" - 0x00, 0x00, // Padding1 (32 bit alignment) - // VS_FIXEDFILEINFO starts - 0xBD, 0x04, 0xEF, 0xFE, // dwSignature (0xFEEF04BD) - 0x00, 0x00, 0x01, 0x00, // dwStrucVersion - }; - byte[] preamble2 = new byte[] { - 0x3F, 0x00, 0x00, 0x00, // dwFileFlagsMask (??) - 0x00, 0x00, 0x00, 0x00, // dwFileFlags (??) - 0x04, 0x00, 0x00, 0x00, // dwFileOS - 0x02, 0x00, 0x00, 0x00, // dwFileType - 0x00, 0x00, 0x00, 0x00, // dwFileSubtype - 0x00, 0x00, 0x00, 0x00, // dwFileDateMS - 0x00, 0x00, 0x00, 0x00, // dwFileDateLS - // Padding2 (32 bit alignment) - // VarFileInfo - 0x44, 0x00, // wLength - 0x00, 0x00, // wValueLength - 0x01, 0x00, // wType - 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x66, 0x00, 0x6F, 0x00, 0x00, 0x00, // "VarFileInfo\0" - 0x00, 0x00, // Padding - // Var - 0x24, 0x00, // wLength - 0x04, 0x00, // wValueLength - 0x00, 0x00, // wType - 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, // "Translation\0" - 0x00, 0x00, // Padding (32 bit alignment) - }; - bb.Write((short)(2 + preamble1.Length + 8 + 8 + preamble2.Length + 4 + stringFileInfo.Length)); - bb.Write(preamble1); - bb.Write((short)fileVersionMinor); - bb.Write((short)fileVersionMajor); - bb.Write((short)fileVersionRevision); - bb.Write((short)fileVersionBuild); - bb.Write((short)productVersionMinor); - bb.Write((short)productVersionMajor); - bb.Write((short)productVersionRevision); - bb.Write((short)productVersionBuild); - bb.Write(preamble2); - bb.Write((short)lcid); - bb.Write((short)codepage); - bb.Write(stringFileInfo); - } - - private static void WriteUTF16Z(ByteBuffer bb, string str) - { - foreach (char c in str) - { - bb.Write((short)c); - } - bb.Write((short)0); - } - - private static void WriteString(ByteBuffer bb, string name, string value) - { - value = value ?? " "; - int pos = bb.Position; - bb.Write((short)0); // wLength (placeholder) - bb.Write((short)(value.Length + 1));// wValueLength - bb.Write((short)1); // wType - WriteUTF16Z(bb, name); - bb.Align(4); - WriteUTF16Z(bb, value); - bb.Align(4); - int savedPos = bb.Position; - bb.Position = pos; - bb.Write((short)(savedPos - pos)); - bb.Position = savedPos; - } - - private static Version ParseVersionRobust(string ver) - { - int index = 0; - ushort major = ParseVersionPart(ver, ref index); - ushort minor = ParseVersionPart(ver, ref index); - ushort build = ParseVersionPart(ver, ref index); - ushort revision = ParseVersionPart(ver, ref index); - return new Version(major, minor, build, revision); - } - - private static ushort ParseVersionPart(string str, ref int pos) - { - ushort value = 0; - while (pos < str.Length) - { - char c = str[pos]; - if (c == '.') - { - pos++; - break; - } - else if (c >= '0' && c <= '9') - { - value *= 10; - value += (ushort)(c - '0'); - pos++; - } - else - { - break; - } - } - return value; - } - } -} diff --git a/mcs/class/IKVM.Reflection/reflect.build b/mcs/class/IKVM.Reflection/reflect.build deleted file mode 100644 index f9c935bf22e..00000000000 --- a/mcs/class/IKVM.Reflection/reflect.build +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mcs/class/Makefile b/mcs/class/Makefile index 3a5a153bff2..cadc5870aba 100644 --- a/mcs/class/Makefile +++ b/mcs/class/Makefile @@ -159,12 +159,19 @@ mobile_dirs := \ Mono.Cairo \ Mono.Data.Sqlite \ System.Numerics \ - System.Data.Services.Client + System.Data.Services.Client \ + System.Reactive.Interfaces \ + System.Reactive.Core \ + System.Reactive.Linq \ + System.Reactive.PlatformServices \ + System.Reactive.Experimental \ + System.Reactive.Debugger monodroid_dirs := \ Mono.CompilerServices.SymbolWriter \ Mono.CSharp \ - Microsoft.CSharp + Microsoft.CSharp \ + System.Reactive.Providers monotouch_runtime_dirs := \ corlib \ @@ -208,6 +215,16 @@ net_4_0_dirs := \ System.Windows.Forms.DataVisualization \ System.Xaml \ WindowsBase \ + System.Reactive.Interfaces \ + System.Reactive.Core \ + System.Reactive.Linq \ + System.Reactive.PlatformServices \ + System.Reactive.Providers \ + System.Reactive.Runtime.Remoting \ + System.Reactive.Windows.Forms \ + System.Reactive.Windows.Threading \ + System.Reactive.Experimental \ + System.Reactive.Debugger \ System.ServiceModel.Routing \ System.ServiceModel.Discovery \ System.Runtime.Caching \ @@ -252,7 +269,7 @@ include ../build/rules.make SUBDIRS = $(common_dirs) $(net_2_0_dirs) $(net_2_0_only_dirs) $(net_3_5_only_dirs) $(moonlight_raw_dirs) $(mobile_dirs) $(net_4_0_dirs) $(net_4_0_only_dirs) $(net_4_5_dirs) -DIST_ONLY_SUBDIRS = dlr IKVM.Reflection aot-compiler +DIST_ONLY_SUBDIRS = dlr aot-compiler # No new makefiles for: System.Messaging, System.Web.Mobile, # System.ServiceProcess @@ -264,6 +281,7 @@ DISTFILES = \ mono.pub \ msfinal.pub \ silverlight.pub \ + reactive.pub \ mono.snk \ LICENSE \ README \ diff --git a/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/MaskedTextBox.xml b/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/MaskedTextBox.xml index 607ba4176a4..b32fbfe9a06 100644 --- a/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/MaskedTextBox.xml +++ b/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/MaskedTextBox.xml @@ -1010,7 +1010,7 @@ - System.ComponentModel.DefaultValue(�) + System.ComponentModel.DefaultValue('\0') System.ComponentModel.RefreshProperties(System.ComponentModel.RefreshProperties.Repaint) diff --git a/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/TextBox.xml b/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/TextBox.xml index 1502e19cd01..f705f03afdc 100644 --- a/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/TextBox.xml +++ b/mcs/class/Managed.Windows.Forms/Documentation/en/System.Windows.Forms/TextBox.xml @@ -380,7 +380,7 @@ System.ComponentModel.RefreshProperties(System.ComponentModel.RefreshProperties.Repaint) - System.ComponentModel.DefaultValue(�) + System.ComponentModel.DefaultValue('\0') System.ComponentModel.Localizable(true) diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/AxHost.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/AxHost.cs index e9ca02ae741..f8343abb9e5 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/AxHost.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/AxHost.cs @@ -557,7 +557,8 @@ namespace System.Windows.Forms { protected override void CreateHandle () { - throw new NotImplementedException("COM/ActiveX support is not implemented"); + if(!base.IsHandleCreated) + base.CreateHandle(); } protected virtual object CreateInstanceCore (Guid clsid) @@ -573,7 +574,7 @@ namespace System.Windows.Forms { protected override void DestroyHandle () { - throw new NotImplementedException("COM/ActiveX support is not implemented"); + base.DestroyHandle(); } [EditorBrowsable (EditorBrowsableState.Advanced)] @@ -584,7 +585,7 @@ namespace System.Windows.Forms { protected override void Dispose (bool disposing) { - throw new NotImplementedException("COM/ActiveX support is not implemented"); + base.Dispose(disposing); } [EditorBrowsable (EditorBrowsableState.Never)] @@ -722,7 +723,7 @@ namespace System.Windows.Forms { protected override void WndProc (ref Message m) { - throw new NotImplementedException("COM/ActiveX support is not implemented"); + this.DefWndProc(ref m); } #endregion // Protected Instance Methods diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs index 711fe5fd282..96bb4769972 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs @@ -70,7 +70,12 @@ namespace Microsoft.Build.Tasks { String.Join (";", defines)); } - commandLine.AppendSwitchIfNotNull ("/nowarn:", DisabledWarnings); + if (!String.IsNullOrEmpty (DisabledWarnings)) { + string [] defines = DisabledWarnings.Split (new char [] {';', ' ', ','}, + StringSplitOptions.RemoveEmptyEntries); + if (defines.Length > 0) + commandLine.AppendSwitchIfNotNull ("/nowarn:", defines, ";"); + } commandLine.AppendSwitchIfNotNull ("/doc:", DocumentationFile); diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CscTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CscTest.cs index f7505b294c4..e72978e064f 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CscTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CscTest.cs @@ -189,6 +189,18 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.AreEqual ("/nowarn:A", clbe.ToString (), "A1"); } + [Test] + public void TestDisabledWarningsComma () + { + CscExtended csc = new CscExtended (); + CommandLineBuilderExtension clbe = new CommandLineBuilderExtension (); + + csc.DisabledWarnings = "A, B"; + csc.ARFC (clbe); + + Assert.AreEqual ("/nowarn:A;B", clbe.ToString (), "A1"); + } + [Test] public void TestDocumentationFile () { diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ResolveAssemblyReferenceTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ResolveAssemblyReferenceTest.cs index 5816d7adf5c..67d386284a3 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ResolveAssemblyReferenceTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ResolveAssemblyReferenceTest.cs @@ -69,7 +69,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.IsTrue (big [0].Include.EndsWith (".dll"), "A3"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_FancyStuff () { engine = new Engine (Consts.BinPath); @@ -86,7 +86,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.IsTrue (big.Cast ().Any (item => item.Include.EndsWith ("SimpleWrite.dll")), "A5"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_SimpleWrite () { engine = new Engine (Consts.BinPath); @@ -102,7 +102,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.AreEqual (0, big.Count, "A4"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_Testing () { engine = new Engine (Consts.BinPath); @@ -118,7 +118,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.AreEqual (0, big.Count, "A4"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_XbuildReferenceBugTest () { engine = new Engine (Consts.BinPath); @@ -137,7 +137,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.IsTrue (big.Cast ().Any (item => item.Include.EndsWith ("Testing.dll")), "A7"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_FancyStuffAndXbuild () { engine = new Engine (Consts.BinPath); @@ -156,7 +156,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Assert.IsTrue (big.Cast ().Any (item => item.Include.EndsWith ("Testing.dll")), "A6"); } - [Test] + [Test, Category("NotWorking")] public void ResolveBinary_SameAssemblyTwice () { engine = new Engine (Consts.BinPath); diff --git a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs index 00589e5605f..82a40ed6c8a 100644 --- a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs +++ b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLite3.cs @@ -49,10 +49,6 @@ namespace Mono.Data.Sqlite { if (bDisposing) Close(); -#if MONOTOUCH - if (gch.IsAllocated) - gch.Free (); -#endif } // It isn't necessary to cleanup any functions we've registered. If the connection @@ -73,6 +69,10 @@ namespace Mono.Data.Sqlite } _sql = null; +#if MONOTOUCH + if (gch.IsAllocated) + gch.Free (); +#endif } internal override void Cancel() diff --git a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs index d1560c3103c..961184bb0d7 100644 --- a/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs +++ b/mcs/class/Mono.Data.Sqlite/Mono.Data.Sqlite_2.0/SQLiteConnection.cs @@ -304,6 +304,9 @@ namespace Mono.Data.Sqlite { base.Dispose(disposing); + if (_sql != null) + _sql.Dispose (); + if (disposing) Close(); } diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs index a5b663b1cd0..cdf7fc6097e 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs @@ -219,6 +219,10 @@ public class Tests : TestsBase unhandled_exception (); return 0; } + if (args.Length >0 && args [0] == "unhandled-exception-user") { + unhandled_exception_user (); + return 0; + } breakpoints (); single_stepping (); arguments (); @@ -423,7 +427,7 @@ public class Tests : TestsBase [MethodImplAttribute (MethodImplOptions.NoInlining)] public static void objects () { - Tests t = new Tests () { field_i = 42, field_bool1 = true, field_bool2 = false, field_char = 'A', field_byte = 129, field_sbyte = -33, field_short = Int16.MaxValue - 5, field_ushort = UInt16.MaxValue - 5, field_long = Int64.MaxValue - 5, field_ulong = UInt64.MaxValue - 5, field_float = 3.14f, field_double = 3.14f, field_s = "S", base_field_i = 43, base_field_s = "T", field_enum = AnEnum.B, field_class = null, field_intptr = new IntPtr (Int32.MaxValue - 5) }; + Tests t = new Tests () { field_i = 42, field_bool1 = true, field_bool2 = false, field_char = 'A', field_byte = 129, field_sbyte = -33, field_short = Int16.MaxValue - 5, field_ushort = UInt16.MaxValue - 5, field_long = Int64.MaxValue - 5, field_ulong = UInt64.MaxValue - 5, field_float = 3.14f, field_double = 3.14f, field_s = "S", base_field_i = 43, base_field_s = "T", field_enum = AnEnum.B, field_class = null, field_intptr = new IntPtr (Int32.MaxValue - 5), field_nullable = null }; t.o1 (new Tests2 () { field_j = 43 }, new GClass { field = 42 }, new GClass { field = "FOO" }); o2 (new string [] { "BAR", "BAZ" }, new int[] { 42, 43 }, new int [,] { { 1, 2 }, { 3, 4 }}, (int[,])Array.CreateInstance (typeof (int), new int [] { 2, 2}, new int [] { 1, 3}), new int[] { 0 }); } @@ -801,6 +805,21 @@ public class Tests : TestsBase Thread.Sleep (10000); } + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static void unhandled_exception_user () { +#if NET_4_5 + System.Threading.Tasks.Task.Factory.StartNew (() => { + Throw (); + }); + Thread.Sleep (10000); +#endif + } + + [MethodImplAttribute (MethodImplOptions.NoInlining)] + public static void Throw () { + throw new Exception (); + } + internal static Delegate create_filter_delegate (Delegate dlg, MethodInfo filter_method) { if (dlg == null) diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index 9b15fbc2af7..ead271375b1 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -2175,8 +2175,6 @@ public class DebuggerTests void invoke_multiple_cb (IAsyncResult ar) { ObjectMirror this_obj = (ObjectMirror)ar.AsyncState; - Console.WriteLine ("CB!"); - var res = this_obj.EndInvokeMethod (ar); lock (invoke_results) invoke_results.Add (res); @@ -3083,6 +3081,29 @@ public class DebuggerTests vm.Exit (0); vm = null; } + +#if NET_4_5 + [Test] + public void UnhandledExceptionUserCode () { + vm.Detach (); + + // Exceptions caught in non-user code are treated as unhandled + Start (new string [] { "dtest-app.exe", "unhandled-exception-user" }); + + var req = vm.CreateExceptionRequest (null, false, true); + req.AssemblyFilter = new List () { entry_point.DeclaringType.Assembly }; + req.Enable (); + + var e = run_until ("unhandled_exception_user"); + vm.Resume (); + + var e2 = GetNextEvent (); + Assert.IsTrue (e2 is ExceptionEvent); + + vm.Exit (0); + vm = null; + } +#endif } } \ No newline at end of file diff --git a/mcs/class/Mono.Options/Documentation/en/Mono.Options/Option.xml b/mcs/class/Mono.Options/Documentation/en/Mono.Options/Option.xml index 661c9a51b79..54923a89ad9 100644 --- a/mcs/class/Mono.Options/Documentation/en/Mono.Options/Option.xml +++ b/mcs/class/Mono.Options/Documentation/en/Mono.Options/Option.xml @@ -126,9 +126,9 @@ This is equivalent to calling the - + constructor as with Option(, - , 1). + , 1,false). @@ -197,8 +197,120 @@ new instance using , the property of the new instance using . and + initializes the + property of the new instance to 1. + + + This is equivalent to calling the + + constructor as with Option(, + , , false). + + + + + is the empty string "". + + -or- + + contains an empty alias, such as + a||b. + + -or- + + Conflicting values + were found within . + + -or- + + is 0 and + specified an + value of + or + . + + -or- + + is greater than 1 and + specified an + value of + . + + -or- + + contains a separator list and + is 0 or 1. + + -or- + + contains a badly formatted + separator list, such as {{, }}, {{}, etc. + + -or- + + only includes the default handler + <> and did not specify an + value of + . + + -or- + + includes the default handler + <>, and is greater + than 1. + + + + is . + + + + + + + Constructor + + 0.2.3.0 + + + + + + + + + + A containing a |-separated + list of option names (aliases) and an optional value-type specifier. + + + A containing documentation for the + option. + + + A containing the number of values this + option accepts. + + + A specifying whether or not the + Option should be displayed in + . + + + Creates and initializes a new instance of the + class. + + + + This constructor initializes the + property of the + new instance using , the + property of the + new instance using , initializes the - property of the new instance using . + property of the new instance using , + and initializes the + property of the new instance using . is a |-separated list of @@ -472,6 +584,33 @@ + + + + Property + + 0.2.3.0 + + + System.Boolean + + + + Whether + + should write this option. + + + If , then + + will not print this option; otherwise, + + will write this option. + + + + + diff --git a/mcs/class/Mono.Options/Documentation/en/Mono.Options/OptionSet.xml b/mcs/class/Mono.Options/Documentation/en/Mono.Options/OptionSet.xml index bddc27c5b67..67225ad7768 100644 --- a/mcs/class/Mono.Options/Documentation/en/Mono.Options/OptionSet.xml +++ b/mcs/class/Mono.Options/Documentation/en/Mono.Options/OptionSet.xml @@ -1402,6 +1402,136 @@ localization: hello:Could not convert string `not-an-int' to type Int32 for opti + + + + Method + + 0.2.3.0 + + + Mono.Options.OptionSet + + + + + + + + + + A containing all option aliases to + register, an (optional) type specifier, and an (optional) value + separator list; see + + for details. + + + A containing to used to initialize + the property. + + + A + to invoke when an option is parsed. + + + A specifying whether or not the + Option should be displayed in + . + + + Registers each alias within so that any + options matching the aliases in will be + handled by during any subsequent + + calls. + + + The current instance. + This is to permit method chaining. + + + + + + has an alias (as returned from + ) that conflicts with + a previously registered . + + + + is + -or- + + is + + + + + + + Method + + 0.2.3.0 + + + Mono.Options.OptionSet + + + + + + + + + + A containing all option aliases to + register, an (optional) type specifier, and an (optional) value + separator list; see + + for details. + + + A containing to used to initialize + the property. + + + A + to invoke when an option is parsed. + + + A specifying whether or not the + Option should be displayed in + . + + + Registers each alias within so that any + options matching the aliases in will be + handled by during any subsequent + + calls. + + + The current instance. + This is to permit method chaining. + + + + + + has an alias (as returned from + ) that conflicts with + a previously registered . + + + + is + -or- + + is + + + @@ -2415,6 +2545,15 @@ class Test { . + + Writes documentation to + . + + + If is + , then the Option will not be written to + . + For each previously added to the current instance, this method writes out a comma-separated diff --git a/mcs/class/Mono.Options/Mono.Options/Options.cs b/mcs/class/Mono.Options/Mono.Options/Options.cs index 6f5dee2d6c7..5af7fe0f387 100644 --- a/mcs/class/Mono.Options/Mono.Options/Options.cs +++ b/mcs/class/Mono.Options/Mono.Options/Options.cs @@ -4,9 +4,11 @@ // Authors: // Jonathan Pryor // Federico Di Gregorio +// Rolf Bjarne Kvinge // // Copyright (C) 2008 Novell (http://www.novell.com) // Copyright (C) 2009 Federico Di Gregorio. +// Copyright (C) 2012 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 @@ -372,13 +374,19 @@ namespace Mono.Options OptionValueType type; int count; string[] separators; + bool hidden; protected Option (string prototype, string description) - : this (prototype, description, 1) + : this (prototype, description, 1, false) { } protected Option (string prototype, string description, int maxValueCount) + : this (prototype, description, maxValueCount, false) + { + } + + protected Option (string prototype, string description, int maxValueCount, bool hidden) { if (prototype == null) throw new ArgumentNullException ("prototype"); @@ -400,6 +408,7 @@ namespace Mono.Options return; this.type = ParsePrototype (); + this.hidden = hidden; if (this.count == 0 && type != OptionValueType.None) throw new ArgumentException ( @@ -422,6 +431,7 @@ namespace Mono.Options public string Description {get {return description;}} public OptionValueType OptionValueType {get {return type;}} public int MaxValueCount {get {return count;}} + public bool Hidden {get {return hidden;}} public string[] GetNames () { @@ -805,7 +815,12 @@ namespace Mono.Options Action action; public ActionOption (string prototype, string description, int count, Action action) - : base (prototype, description, count) + : this (prototype, description, count, action, false) + { + } + + public ActionOption (string prototype, string description, int count, Action action, bool hidden) + : base (prototype, description, count, hidden) { if (action == null) throw new ArgumentNullException ("action"); @@ -824,11 +839,16 @@ namespace Mono.Options } public OptionSet Add (string prototype, string description, Action action) + { + return Add (prototype, description, action, false); + } + + public OptionSet Add (string prototype, string description, Action action, bool hidden) { if (action == null) throw new ArgumentNullException ("action"); Option p = new ActionOption (prototype, description, 1, - delegate (OptionValueCollection v) { action (v [0]); }); + delegate (OptionValueCollection v) { action (v [0]); }, hidden); base.Add (p); return this; } @@ -840,10 +860,14 @@ namespace Mono.Options public OptionSet Add (string prototype, string description, OptionAction action) { + return Add (prototype, description, action, false); + } + + public OptionSet Add (string prototype, string description, OptionAction action, bool hidden) { if (action == null) throw new ArgumentNullException ("action"); Option p = new ActionOption (prototype, description, 2, - delegate (OptionValueCollection v) {action (v [0], v [1]);}); + delegate (OptionValueCollection v) {action (v [0], v [1]);}, hidden); base.Add (p); return this; } @@ -1150,6 +1174,9 @@ namespace Mono.Options foreach (Option p in this) { int written = 0; + if (p.Hidden) + continue; + Category c = p as Category; if (c != null) { WriteDescription (o, p.Description, "", 80, 80); diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs index 3992ee03fd5..666bad54d5b 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs @@ -386,6 +386,8 @@ namespace Tests.Mono.Options { var p = new OptionSet () { "\n:Category 1:", + { "hidden", "hidden option, invisible in help", v => {}, true }, + { "hidden2=", "hidden option, invisible in help", (k, v) => {}, true }, { "p|indicator-style=", "append / indicator to directories", v => {} }, { "color:", "controls color info", v => {} }, { "color2:", "set {color}", v => {} }, diff --git a/mcs/class/Mono.Posix/Documentation/en/Mono.Posix/Syscall.xml b/mcs/class/Mono.Posix/Documentation/en/Mono.Posix/Syscall.xml index ac0aa729e51..e71898ffdde 100644 --- a/mcs/class/Mono.Posix/Documentation/en/Mono.Posix/Syscall.xml +++ b/mcs/class/Mono.Posix/Documentation/en/Mono.Posix/Syscall.xml @@ -684,32 +684,6 @@ class Test This member is obsolete. Please use instead. - See also GetHostName() - - - - - - - - - Method - - 1.0.5000.0 - 2.0.0.0 - 4.0.0.0 - - - System.String - - - - Retrieves the hostname. - a - - This member is obsolete. Please use - instead. - Either GetHostName() should be removed, since gethostname() also exists, or the entire library should be CamelCased per .NET standard. diff --git a/mcs/class/Mono.Reactive.Testing/Makefile b/mcs/class/Mono.Reactive.Testing/Makefile new file mode 100644 index 00000000000..c02117a6ddf --- /dev/null +++ b/mcs/class/Mono.Reactive.Testing/Makefile @@ -0,0 +1,48 @@ +thisdir = class/Mono.Reactive.Testing +SUBDIRS = +include ../../build/rules.make + +LIBRARY = Mono.Reactive.Testing.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll \ + -r:System.Reactive.PlatformServices.dll \ + -r:System.Reactive.Providers.dll \ + -r:System.Reactive.Runtime.Remoting.dll \ + -r:System.Reactive.Experimental.dll \ + -r:System.Reactive.Windows.Forms.dll \ + -r:System.Reactive.Windows.Threading.dll \ + -r:System.Windows.Forms.dll \ + -r:WindowsBase.dll \ + -r:nunit.framework.dll \ + -d:NUNIT -d:MONO -d:DESKTOPCLR + # NO_PERF is required to disable ObservableMultipleTest.Catch_TailRecursive2 which blocked test execution. + # disabled -d:HAS_WINFORMS + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -nowarn:0618 + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.Mono.Reactive.Testing.dll +NO_INSTALL = yes +NO_TEST = yes +endif + +NO_SIGN_ASSEMBLY = yes + +include ../../build/library.make diff --git a/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing.dll.sources b/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing.dll.sources new file mode 100644 index 00000000000..964a9c5f051 --- /dev/null +++ b/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing.dll.sources @@ -0,0 +1,13 @@ +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/ColdObservable.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/GlobalSuppressions.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/HotObservable.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/ITestObservable.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/ITestObserver.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/MockObserver.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/NamespaceDoc.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/ReactiveAssert.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/ReactiveTest.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/Recorded.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/Subscription.cs +../../../external/rx/Rx.NET/Microsoft.Reactive.Testing/TestScheduler.cs diff --git a/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing_test.dll.sources b/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing_test.dll.sources new file mode 100644 index 00000000000..8971bf1a055 --- /dev/null +++ b/mcs/class/Mono.Reactive.Testing/Mono.Reactive.Testing_test.dll.sources @@ -0,0 +1,83 @@ +../../../../external/rx/Rx.NET/Tests.System.Reactive/App.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/DispatcherHelpers.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Semaphore.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Core/Disposables/Composite.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Core/Disposables/Serial.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Core/Disposables/SingleAssignment.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Core/Disposables/RefCount.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Linq/Delay.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Linq/FromEvent.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Helpers.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Stress/Linq/Replay.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/TestBase.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/TestLongRunningScheduler.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/AnonymousTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/AsyncLockTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ConcurrencyTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ConnectableObservable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ConnectableObservableTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ControlSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableSafetyTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/QbservableExTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/RogueEnumerable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ScheduledItemTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/StopwatchTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/SystemClockTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/DefaultConcurrencyAbstractionLayerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/EventPatternSourceBaseTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/SynchronizationTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/DefaultSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/CurrentThreadSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/DisposableTests.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/EventLoopSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/HistoricalSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ImmediateSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/MySubject.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/NewThreadSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/NotificationTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableEventsTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableImperativeTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/SchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/SynchronizationContextSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/TaskObservableExtensionsTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/TaskPoolSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ThreadPoolSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/TimeTests.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/UnitTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/VirtualSchedulerTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyDisposable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyEnumerable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyFunc.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyObservable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyObserver.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Dummies/DummyScheduler.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Extensions.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/MockDisposable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/MockEnumerable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/NullErrorObservable.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Properties/AssemblyInfo.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/AsyncSubjectTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/BehaviorSubjectTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/SubjectTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ListObservableTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableAggregateTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableAsyncTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableAwaiterTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableBindingTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableBlockingTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableConversionTests.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableCreationTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableExtensionsTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableJoinsTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableMultipleTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableRemotingTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableSingleTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableStandardQueryOperatorTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableTimeTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObserverTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/PrivateTypesTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/QbservableTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/RegressionTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ReplaySubjectTest.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/TestTaskScheduler.cs +../../../../external/rx/Rx.NET/Tests.System.Reactive/Utils.cs diff --git a/mcs/class/Mono.Reactive.Testing/more_build_args b/mcs/class/Mono.Reactive.Testing/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/Mono.Reactive.Testing/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD2.xml b/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD2.xml deleted file mode 100644 index f111ba12edd..00000000000 --- a/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD2.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - Mono.Security.Win32 - [00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 79 15 99 77 D2 D0 3A 8E 6B EA 7A 2E 74 E8 D1 AF CC 93 E8 85 19 74 95 2B B4 80 A1 2C 91 34 47 4D 04 06 24 47 C3 7E 0E 68 C0 80 53 6F CF 3C 3F BE 2F F9 C9 79 CE 99 84 75 E5 06 E8 CE 82 DD 5B 0F 35 0D C1 0E 93 BF 2E EE CF 87 4B 24 77 0C 50 81 DB EA 74 47 FD DA FA 27 7B 22 DE 47 D6 FF EA 44 96 74 A4 F9 FC CF 84 D1 50 69 08 93 80 28 4D BD D3 5F 46 CD FF 12 A1 BD 78 E4 EF 00 65 D0 16 DF] - 1.0.5000.0 - 2.0.0.0 - - Gtk# is thread aware, but not thread safe; See the Gtk# Thread Programming for details. - - System.Security.Cryptography.HashAlgorithm - - - - - Common base class for all derived MD2 implementations. - This class isn't CryptoAPI related. It is included here so that Mono.Security.dll doesn't have any dependencies on assemblies other than mscorlib.dll. - - - - - Constructor - - - - To be added - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - - Method - - Mono.Security.Cryptography.MD2 - - - - Creates the default derived class. - a - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - - Method - - Mono.Security.Cryptography.MD2 - - - - - - Specifies which derived class to create. - Creates a new derived class. - a - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - diff --git a/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD4.xml b/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD4.xml deleted file mode 100644 index 73cb8440a45..00000000000 --- a/mcs/class/Mono.Security.Win32/Documentation/en/Mono.Security.Cryptography/MD4.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - Mono.Security.Win32 - [00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00 79 15 99 77 D2 D0 3A 8E 6B EA 7A 2E 74 E8 D1 AF CC 93 E8 85 19 74 95 2B B4 80 A1 2C 91 34 47 4D 04 06 24 47 C3 7E 0E 68 C0 80 53 6F CF 3C 3F BE 2F F9 C9 79 CE 99 84 75 E5 06 E8 CE 82 DD 5B 0F 35 0D C1 0E 93 BF 2E EE CF 87 4B 24 77 0C 50 81 DB EA 74 47 FD DA FA 27 7B 22 DE 47 D6 FF EA 44 96 74 A4 F9 FC CF 84 D1 50 69 08 93 80 28 4D BD D3 5F 46 CD FF 12 A1 BD 78 E4 EF 00 65 D0 16 DF] - 1.0.5000.0 - 2.0.0.0 - - Gtk# is thread aware, but not thread safe; See the Gtk# Thread Programming for details. - - System.Security.Cryptography.HashAlgorithm - - - - - Common base class for all derived MD4 implementations. - This class isn't CryptoAPI related. It is included here so that Mono.Security.dll doesn't have any dependencies on assemblies other than mscorlib.dll. - - - - - Constructor - - - - To be added - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - - Method - - Mono.Security.Cryptography.MD4 - - - - Creates the default derived class. - a - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - - Method - - Mono.Security.Cryptography.MD4 - - - - - - Specifies which derived class to create. - Creates a new derived class. - a - To be added - - - 1.0.5000.0 - 2.0.0.0 - - - - diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse.cs index e8a0b8a1482..7a8456bb744 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse.cs @@ -45,6 +45,7 @@ using Mono.Security.Cryptography; namespace Mono.Security.Protocol.Ntlm { + [Obsolete (Type3Message.LegacyAPIWarning)] public class ChallengeResponse : IDisposable { static private byte[] magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse2.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse2.cs new file mode 100644 index 00000000000..5479520f885 --- /dev/null +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/ChallengeResponse2.cs @@ -0,0 +1,295 @@ +// +// Mono.Security.Protocol.Ntlm.ChallengeResponse +// Implements Challenge Response for NTLM v1 and NTLM v2 Session +// +// Authors: +// Sebastien Pouliot +// Martin Baulig +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// (C) 2004 Novell (http://www.novell.com) +// (C) 2012 Xamarin, Inc. (http://www.xamarin.com) +// +// References +// a. NTLM Authentication Scheme for HTTP, Ronald Tschalär +// http://www.innovation.ch/java/ntlm.html +// b. The NTLM Authentication Protocol, Copyright © 2003 Eric Glass +// http://davenport.sourceforge.net/ntlm.html +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; +using System.Net; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +using Mono.Security.Cryptography; + +namespace Mono.Security.Protocol.Ntlm { + + public static class ChallengeResponse2 { + + static private byte[] magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; + + // This is the pre-encrypted magic value with a null DES key (0xAAD3B435B51404EE) + // Ref: http://packetstormsecurity.nl/Crackers/NT/l0phtcrack/l0phtcrack2.5-readme.html + static private byte[] nullEncMagic = { 0xAA, 0xD3, 0xB4, 0x35, 0xB5, 0x14, 0x04, 0xEE }; + + static byte[] Compute_LM (string password, byte[] challenge) + { + var buffer = new byte [21]; + + // create Lan Manager password +#if MOONLIGHT + DESCryptoServiceProvider des = new DESCryptoServiceProvider (); +#else + DES des = DES.Create (); +#endif + des.Mode = CipherMode.ECB; + ICryptoTransform ct = null; + + // Note: In .NET DES cannot accept a weak key + // this can happen for a null password + if ((password == null) || (password.Length < 1)) { + Buffer.BlockCopy (nullEncMagic, 0, buffer, 0, 8); + } else { + des.Key = PasswordToKey (password, 0); + ct = des.CreateEncryptor (); + ct.TransformBlock (magic, 0, 8, buffer, 0); + } + + // and if a password has less than 8 characters + if ((password == null) || (password.Length < 8)) { + Buffer.BlockCopy (nullEncMagic, 0, buffer, 8, 8); + } else { + des.Key = PasswordToKey (password, 7); + ct = des.CreateEncryptor (); + ct.TransformBlock (magic, 0, 8, buffer, 8); + } + + des.Clear (); + + return GetResponse (challenge, buffer); + } + + static byte[] Compute_NTLM_Password (string password) + { + var buffer = new byte [21]; + + // create NT password +#if MOONLIGHT + MD4Managed md4 = new MD4Managed (); +#else + MD4 md4 = MD4.Create (); +#endif + byte[] data = ((password == null) ? (new byte [0]) : (Encoding.Unicode.GetBytes (password))); + byte[] hash = md4.ComputeHash (data); + Buffer.BlockCopy (hash, 0, buffer, 0, 16); + + // clean up + Array.Clear (data, 0, data.Length); + Array.Clear (hash, 0, hash.Length); + + return buffer; + } + + static byte[] Compute_NTLM (string password, byte[] challenge) + { + var buffer = Compute_NTLM_Password (password); + return GetResponse (challenge, buffer); + } + + static void Compute_NTLMv2_Session (string password, byte[] challenge, + out byte[] lm, out byte[] ntlm) + { + var nonce = new byte [8]; + var rng = RandomNumberGenerator.Create (); + rng.GetBytes (nonce); + + var sessionNonce = new byte [challenge.Length + 8]; + challenge.CopyTo (sessionNonce, 0); + nonce.CopyTo (sessionNonce, challenge.Length); + + lm = new byte [24]; + nonce.CopyTo (lm, 0); + +#if MOONLIGHT + MD5Managed md5 = new MD5Managed (); +#else + MD5 md5 = MD5.Create (); +#endif + + var hash = md5.ComputeHash (sessionNonce); + var newChallenge = new byte [8]; + Array.Copy (hash, newChallenge, 8); + + ntlm = Compute_NTLM (password, newChallenge); + + // clean up + Array.Clear (nonce, 0, nonce.Length); + Array.Clear (sessionNonce, 0, sessionNonce.Length); + Array.Clear (newChallenge, 0, newChallenge.Length); + Array.Clear (hash, 0, hash.Length); + } + + static byte[] Compute_NTLMv2 (Type2Message type2, string username, string password) + { + var ntlm_hash = Compute_NTLM_Password (password); + + var ubytes = Encoding.Unicode.GetBytes (username.ToUpperInvariant ()); + var tbytes = Encoding.Unicode.GetBytes (type2.TargetName.ToUpperInvariant ()); + + var bytes = new byte [ubytes.Length + tbytes.Length]; + ubytes.CopyTo (bytes, 0); + Array.Copy (tbytes, 0, bytes, ubytes.Length, tbytes.Length); + + var md5 = new HMACMD5 (ntlm_hash); + var ntlm_v2_hash = md5.ComputeHash (bytes); + + Array.Clear (ntlm_hash, 0, ntlm_hash.Length); + md5.Clear (); + + var ntlm_v2_md5 = new HMACMD5 (ntlm_v2_hash); + + var now = DateTime.Now; + var timestamp = now.Ticks - 504911232000000000; + + var nonce = new byte [8]; + var rng = RandomNumberGenerator.Create (); + rng.GetBytes (nonce); + + byte[] blob = new byte [28 + type2.TargetInfo.Length]; + blob[0] = 0x01; + blob[1] = 0x01; + + Buffer.BlockCopy (BitConverterLE.GetBytes (timestamp), 0, blob, 8, 8); + + Buffer.BlockCopy (nonce, 0, blob, 16, 8); + Buffer.BlockCopy (type2.TargetInfo, 0, blob, 28, type2.TargetInfo.Length); + + var challenge = type2.Nonce; + + var hashInput = new byte [challenge.Length + blob.Length]; + challenge.CopyTo (hashInput, 0); + blob.CopyTo (hashInput, challenge.Length); + + var blobHash = ntlm_v2_md5.ComputeHash (hashInput); + + var response = new byte [blob.Length + blobHash.Length]; + blobHash.CopyTo (response, 0); + blob.CopyTo (response, blobHash.Length); + + Array.Clear (ntlm_v2_hash, 0, ntlm_v2_hash.Length); + ntlm_v2_md5.Clear (); + Array.Clear (nonce, 0, nonce.Length); + Array.Clear (blob, 0, blob.Length); + Array.Clear (hashInput, 0, hashInput.Length); + Array.Clear (blobHash, 0, blobHash.Length); + + return response; + } + + public static void Compute (Type2Message type2, NtlmAuthLevel level, + string username, string password, + out byte[] lm, out byte[] ntlm) + { + lm = null; + + switch (level) { + case NtlmAuthLevel.LM_and_NTLM: + lm = Compute_LM (password, type2.Nonce); + ntlm = Compute_NTLM (password, type2.Nonce); + break; + + case NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session: + if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) == 0) + goto case NtlmAuthLevel.LM_and_NTLM; + Compute_NTLMv2_Session (password, type2.Nonce, out lm, out ntlm); + break; + + case NtlmAuthLevel.NTLM_only: + if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0) + Compute_NTLMv2_Session (password, type2.Nonce, out lm, out ntlm); + else + ntlm = Compute_NTLM (password, type2.Nonce); + break; + + case NtlmAuthLevel.NTLMv2_only: + ntlm = Compute_NTLMv2 (type2, username, password); + break; + + default: + throw new InvalidOperationException (); + } + } + + static byte[] GetResponse (byte[] challenge, byte[] pwd) + { + byte[] response = new byte [24]; +#if MOONLIGHT + DESCryptoServiceProvider des = new DESCryptoServiceProvider (); +#else + DES des = DES.Create (); +#endif + des.Mode = CipherMode.ECB; + des.Key = PrepareDESKey (pwd, 0); + ICryptoTransform ct = des.CreateEncryptor (); + ct.TransformBlock (challenge, 0, 8, response, 0); + des.Key = PrepareDESKey (pwd, 7); + ct = des.CreateEncryptor (); + ct.TransformBlock (challenge, 0, 8, response, 8); + des.Key = PrepareDESKey (pwd, 14); + ct = des.CreateEncryptor (); + ct.TransformBlock (challenge, 0, 8, response, 16); + return response; + } + + static byte[] PrepareDESKey (byte[] key56bits, int position) + { + // convert to 8 bytes + byte[] key = new byte [8]; + key [0] = key56bits [position]; + key [1] = (byte) ((key56bits [position] << 7) | (key56bits [position + 1] >> 1)); + key [2] = (byte) ((key56bits [position + 1] << 6) | (key56bits [position + 2] >> 2)); + key [3] = (byte) ((key56bits [position + 2] << 5) | (key56bits [position + 3] >> 3)); + key [4] = (byte) ((key56bits [position + 3] << 4) | (key56bits [position + 4] >> 4)); + key [5] = (byte) ((key56bits [position + 4] << 3) | (key56bits [position + 5] >> 5)); + key [6] = (byte) ((key56bits [position + 5] << 2) | (key56bits [position + 6] >> 6)); + key [7] = (byte) (key56bits [position + 6] << 1); + return key; + } + + static byte[] PasswordToKey (string password, int position) + { + byte[] key7 = new byte [7]; + int len = System.Math.Min (password.Length - position, 7); + Encoding.ASCII.GetBytes (password.ToUpper (CultureInfo.CurrentCulture), position, len, key7, 0); + byte[] key8 = PrepareDESKey (key7, 0); + // cleanup intermediate key material + Array.Clear (key7, 0, key7.Length); + return key8; + } + } +} diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/NtlmAuthLevel.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/NtlmAuthLevel.cs new file mode 100644 index 00000000000..e66d5901b5b --- /dev/null +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/NtlmAuthLevel.cs @@ -0,0 +1,55 @@ +// +// NtlmAuthLevel.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; + +namespace Mono.Security.Protocol.Ntlm { + + /* + * On Windows, this is controlled by a registry setting + * (http://msdn.microsoft.com/en-us/library/ms814176.aspx) + * + * This can be configured by setting the static + * Type3Message.DefaultAuthLevel property, the default value + * is LM_and_NTLM_and_try_NTLMv2_Session. + */ + + public enum NtlmAuthLevel { + /* Use LM and NTLM, never use NTLMv2 session security. */ + LM_and_NTLM, + + /* Use NTLMv2 session security if the server supports it, + * otherwise fall back to LM and NTLM. */ + LM_and_NTLM_and_try_NTLMv2_Session, + + /* Use NTLMv2 session security if the server supports it, + * otherwise fall back to NTLM. Never use LM. */ + NTLM_only, + + /* Use NTLMv2 only. */ + NTLMv2_only, + } +} + diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type2Message.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type2Message.cs index 4db26d79135..a2f65e3e584 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type2Message.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type2Message.cs @@ -34,6 +34,7 @@ // using System; +using System.Text; using System.Security.Cryptography; namespace Mono.Security.Protocol.Ntlm { @@ -41,6 +42,8 @@ namespace Mono.Security.Protocol.Ntlm { public class Type2Message : MessageBase { private byte[] _nonce; + private string _targetName; + private byte[] _targetInfo; public Type2Message () : base (2) { @@ -78,15 +81,42 @@ namespace Mono.Security.Protocol.Ntlm { } } + public string TargetName { + get { return _targetName; } + } + + public byte[] TargetInfo { + get { return (byte[])_targetInfo.Clone (); } + } + // methods - protected override void Decode (byte[] message) + protected override void Decode (byte[] message) { base.Decode (message); - Flags = (NtlmFlags) BitConverterLE.ToUInt32 (message, 20); + Flags = (NtlmFlags)BitConverterLE.ToUInt32 (message, 20); Buffer.BlockCopy (message, 24, _nonce, 0, 8); + + var tname_len = BitConverterLE.ToUInt16 (message, 12); + var tname_off = BitConverterLE.ToUInt16 (message, 16); + if (tname_len > 0) { + if ((Flags & NtlmFlags.NegotiateOem) != 0) + _targetName = Encoding.ASCII.GetString (message, tname_off, tname_len); + else + _targetName = Encoding.Unicode.GetString (message, tname_off, tname_len); + } + + // The Target Info block is optional. + if (message.Length >= 48) { + var tinfo_len = BitConverterLE.ToUInt16 (message, 40); + var tinfo_off = BitConverterLE.ToUInt16 (message, 44); + if (tinfo_len > 0) { + _targetInfo = new byte [tinfo_len]; + Buffer.BlockCopy (message, tinfo_off, _targetInfo, 0, tinfo_len); + } + } } public override byte[] GetBytes () diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs index 4662ae92b3f..59e948fdfd9 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Ntlm/Type3Message.cs @@ -41,20 +41,38 @@ namespace Mono.Security.Protocol.Ntlm { public class Type3Message : MessageBase { + private NtlmAuthLevel _level; private byte[] _challenge; private string _host; private string _domain; private string _username; private string _password; + private Type2Message _type2; private byte[] _lm; private byte[] _nt; - + + internal const string LegacyAPIWarning = + "Use of this API is highly discouraged, " + + "it selects legacy-mode LM/NTLM authentication, which sends " + + "your password in very weak encryption over the wire even if " + + "the server supports the more secure NTLMv2 / NTLMv2 Session. " + + "You need to use the new `Type3Message (Type2Message)' constructor " + + "to use the more secure NTLMv2 / NTLMv2 Session authentication modes. " + + "These require the Type 2 message from the server to compute the response."; + + [Obsolete (LegacyAPIWarning)] public Type3Message () : base (3) { + if (DefaultAuthLevel != NtlmAuthLevel.LM_and_NTLM) + throw new InvalidOperationException ( + "Refusing to use legacy-mode LM/NTLM authentication " + + "unless explicitly enabled using DefaultAuthLevel."); + // default values _domain = Environment.UserDomainName; _host = Environment.MachineName; _username = Environment.UserName; + _level = NtlmAuthLevel.LM_and_NTLM; Flags = (NtlmFlags) 0x8201; } @@ -63,6 +81,26 @@ namespace Mono.Security.Protocol.Ntlm { Decode (message); } + public Type3Message (Type2Message type2) : base (3) + { + _type2 = type2; + _level = DefaultAuthLevel; + _challenge = (byte[]) type2.Nonce.Clone (); + + _domain = type2.TargetName; + _host = Environment.MachineName; + _username = Environment.UserName; + + Flags = (NtlmFlags) 0x8200; + if ((type2.Flags & NtlmFlags.NegotiateUnicode) != 0) + Flags |= NtlmFlags.NegotiateUnicode; + else + Flags |= NtlmFlags.NegotiateOem; + + if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0) + Flags |= NtlmFlags.NegotiateNtlm2Key; + } + ~Type3Message () { if (_challenge != null) @@ -73,14 +111,34 @@ namespace Mono.Security.Protocol.Ntlm { Array.Clear (_nt, 0, _nt.Length); } + // Default auth level + + static NtlmAuthLevel _default = NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session; + + public static NtlmAuthLevel DefaultAuthLevel { + get { return _default; } + set { _default = value; } + } + + public NtlmAuthLevel Level { + get { return _level; } + set { _level = value; } + } + // properties + [Obsolete (LegacyAPIWarning)] public byte[] Challenge { get { if (_challenge == null) return null; return (byte[]) _challenge.Clone (); } set { + if ((_type2 != null) || (_level != NtlmAuthLevel.LM_and_NTLM)) + throw new InvalidOperationException ( + "Refusing to use legacy-mode LM/NTLM authentication " + + "unless explicitly enabled using DefaultAuthLevel."); + if (value == null) throw new ArgumentNullException ("Challenge"); if (value.Length != 8) { @@ -94,6 +152,9 @@ namespace Mono.Security.Protocol.Ntlm { public string Domain { get { return _domain; } set { + if (_type2 != null) + throw new InvalidOperationException ( + "Domain is set automatically from Type2Message.TargetName"); if (value == null) value = ""; if (value == "") @@ -135,11 +196,12 @@ namespace Mono.Security.Protocol.Ntlm { public byte[] NT { get { return _nt; } + set { _nt = value; } } // methods - protected override void Decode (byte[] message) + protected override void Decode (byte[] message) { base.Decode (message); @@ -150,105 +212,154 @@ namespace Mono.Security.Protocol.Ntlm { _password = null; - int dom_len = BitConverterLE.ToUInt16 (message, 28); - int dom_off = 64; - _domain = Encoding.Unicode.GetString (message, dom_off, dom_len); + if (message.Length >= 64) + Flags = (NtlmFlags)BitConverterLE.ToUInt32 (message, 60); + else + Flags = (NtlmFlags)0x8201; + + int lm_len = BitConverterLE.ToUInt16 (message, 12); + int lm_off = BitConverterLE.ToUInt16 (message, 16); + _lm = new byte [lm_len]; + Buffer.BlockCopy (message, lm_off, _lm, 0, lm_len); - int host_len = BitConverterLE.ToUInt16 (message, 44); - int host_off = BitConverterLE.ToUInt16 (message, 48); - _host = Encoding.Unicode.GetString (message, host_off, host_len); + int nt_len = BitConverterLE.ToUInt16 (message, 20); + int nt_off = BitConverterLE.ToUInt16 (message, 24); + _nt = new byte [nt_len]; + Buffer.BlockCopy (message, nt_off, _nt, 0, nt_len); + + int dom_len = BitConverterLE.ToUInt16 (message, 28); + int dom_off = BitConverterLE.ToUInt16 (message, 32); + _domain = DecodeString (message, dom_off, dom_len); int user_len = BitConverterLE.ToUInt16 (message, 36); int user_off = BitConverterLE.ToUInt16 (message, 40); - _username = Encoding.Unicode.GetString (message, user_off, user_len); - - _lm = new byte [24]; - int lm_off = BitConverterLE.ToUInt16 (message, 16); - Buffer.BlockCopy (message, lm_off, _lm, 0, 24); + _username = DecodeString (message, user_off, user_len); - _nt = new byte [24]; - int nt_off = BitConverterLE.ToUInt16 (message, 24); - Buffer.BlockCopy (message, nt_off, _nt, 0, 24); + int host_len = BitConverterLE.ToUInt16 (message, 44); + int host_off = BitConverterLE.ToUInt16 (message, 48); + _host = DecodeString (message, host_off, host_len); + + // Session key. We don't use it yet. + // int skey_len = BitConverterLE.ToUInt16 (message, 52); + // int skey_off = BitConverterLE.ToUInt16 (message, 56); + } - if (message.Length >= 64) - Flags = (NtlmFlags) BitConverterLE.ToUInt32 (message, 60); + string DecodeString (byte[] buffer, int offset, int len) + { + if ((Flags & NtlmFlags.NegotiateUnicode) != 0) + return Encoding.Unicode.GetString (buffer, offset, len); + else + return Encoding.ASCII.GetString (buffer, offset, len); + } + + byte[] EncodeString (string text) + { + if (text == null) + return new byte [0]; + if ((Flags & NtlmFlags.NegotiateUnicode) != 0) + return Encoding.Unicode.GetBytes (text); + else + return Encoding.ASCII.GetBytes (text); } - public override byte[] GetBytes () + public override byte[] GetBytes () { - byte[] domain = Encoding.Unicode.GetBytes (_domain.ToUpper (CultureInfo.InvariantCulture)); - byte[] user = Encoding.Unicode.GetBytes (_username); - byte[] host = Encoding.Unicode.GetBytes (_host.ToUpper (CultureInfo.InvariantCulture)); + byte[] target = EncodeString (_domain); + byte[] user = EncodeString (_username); + byte[] host = EncodeString (_host); + + byte[] lm, ntlm; + if (_type2 == null) { + if (_level != NtlmAuthLevel.LM_and_NTLM) + throw new InvalidOperationException ( + "Refusing to use legacy-mode LM/NTLM authentication " + + "unless explicitly enabled using DefaultAuthLevel."); + + using (var legacy = new ChallengeResponse (_password, _challenge)) { + lm = legacy.LM; + ntlm = legacy.NT; + } + } else { + ChallengeResponse2.Compute (_type2, _level, _username, _password, out lm, out ntlm); + } + + var lmresp_len = lm != null ? lm.Length : 0; + var ntresp_len = ntlm != null ? ntlm.Length : 0; - byte[] data = PrepareMessage (64 + domain.Length + user.Length + host.Length + 24 + 24); + byte[] data = PrepareMessage (64 + target.Length + user.Length + host.Length + lmresp_len + ntresp_len); // LM response - short lmresp_off = (short)(64 + domain.Length + user.Length + host.Length); - data [12] = (byte) 0x18; - data [13] = (byte) 0x00; - data [14] = (byte) 0x18; - data [15] = (byte) 0x00; - data [16] = (byte) lmresp_off; + short lmresp_off = (short)(64 + target.Length + user.Length + host.Length); + data [12] = (byte)lmresp_len; + data [13] = (byte)0x00; + data [14] = (byte)lmresp_len; + data [15] = (byte)0x00; + data [16] = (byte)lmresp_off; data [17] = (byte)(lmresp_off >> 8); // NT response - short ntresp_off = (short)(lmresp_off + 24); - data [20] = (byte) 0x18; - data [21] = (byte) 0x00; - data [22] = (byte) 0x18; - data [23] = (byte) 0x00; - data [24] = (byte) ntresp_off; + short ntresp_off = (short)(lmresp_off + lmresp_len); + data [20] = (byte)ntresp_len; + data [21] = (byte)(ntresp_len >> 8); + data [22] = (byte)ntresp_len; + data [23] = (byte)(ntresp_len >> 8); + data [24] = (byte)ntresp_off; data [25] = (byte)(ntresp_off >> 8); - // domain - short dom_len = (short)domain.Length; + // target + short dom_len = (short)target.Length; short dom_off = 64; - data [28] = (byte) dom_len; + data [28] = (byte)dom_len; data [29] = (byte)(dom_len >> 8); data [30] = data [28]; data [31] = data [29]; - data [32] = (byte) dom_off; + data [32] = (byte)dom_off; data [33] = (byte)(dom_off >> 8); // username short uname_len = (short)user.Length; short uname_off = (short)(dom_off + dom_len); - data [36] = (byte) uname_len; + data [36] = (byte)uname_len; data [37] = (byte)(uname_len >> 8); data [38] = data [36]; data [39] = data [37]; - data [40] = (byte) uname_off; + data [40] = (byte)uname_off; data [41] = (byte)(uname_off >> 8); // host short host_len = (short)host.Length; short host_off = (short)(uname_off + uname_len); - data [44] = (byte) host_len; + data [44] = (byte)host_len; data [45] = (byte)(host_len >> 8); data [46] = data [44]; data [47] = data [45]; - data [48] = (byte) host_off; + data [48] = (byte)host_off; data [49] = (byte)(host_off >> 8); // message length short msg_len = (short)data.Length; - data [56] = (byte) msg_len; + data [56] = (byte)msg_len; data [57] = (byte)(msg_len >> 8); + int flags = (int)Flags; + // options flags - data [60] = (byte) Flags; - data [61] = (byte)((uint)Flags >> 8); - data [62] = (byte)((uint)Flags >> 16); - data [63] = (byte)((uint)Flags >> 24); + data [60] = (byte)flags; + data [61] = (byte)((uint)flags >> 8); + data [62] = (byte)((uint)flags >> 16); + data [63] = (byte)((uint)flags >> 24); - Buffer.BlockCopy (domain, 0, data, dom_off, domain.Length); + Buffer.BlockCopy (target, 0, data, dom_off, target.Length); Buffer.BlockCopy (user, 0, data, uname_off, user.Length); Buffer.BlockCopy (host, 0, data, host_off, host.Length); - using (ChallengeResponse ntlm = new ChallengeResponse (_password, _challenge)) { - Buffer.BlockCopy (ntlm.LM, 0, data, lmresp_off, 24); - Buffer.BlockCopy (ntlm.NT, 0, data, ntresp_off, 24); + if (lm != null) { + Buffer.BlockCopy (lm, 0, data, lmresp_off, lm.Length); + Array.Clear (lm, 0, lm.Length); } + Buffer.BlockCopy (ntlm, 0, data, ntresp_off, ntlm.Length); + Array.Clear (ntlm, 0, ntlm.Length); + return data; } } diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientHello.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientHello.cs index 2bb1d7bb8ef..42ca34523a4 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientHello.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsClientHello.cs @@ -23,6 +23,7 @@ // using System; +using System.Net; using System.Security.Cryptography; namespace Mono.Security.Protocol.Tls.Handshake.Client @@ -63,15 +64,10 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client #region Protected Methods protected override void ProcessAsSsl3() - { - this.ProcessAsTls1(); - } - - protected override void ProcessAsTls1() { // Client Version this.Write(this.Context.Protocol); - + // Random bytes - Unix time + Radom bytes [28] TlsStream clientRandom = new TlsStream(); clientRandom.Write(this.Context.GetUnixTime()); @@ -111,10 +107,23 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client // Compression methods ( 0 = none ) this.Write((byte)this.Context.CompressionMethod); + } + protected override void ProcessAsTls1() + { + ProcessAsSsl3 (); + + // If applicable add the "server_name" extension to the hello message // http://www.ietf.org/rfc/rfc3546.txt + string host = Context.ClientSettings.TargetHost; + // Our TargetHost might be an address (not a host *name*) - see bug #8553 + // RFC3546 -> Literal IPv4 and IPv6 addresses are not permitted in "HostName". + IPAddress addr; + if (IPAddress.TryParse (host, out addr)) + return; + TlsStream extensions = new TlsStream (); - byte[] server_name = System.Text.Encoding.UTF8.GetBytes (Context.ClientSettings.TargetHost); + byte[] server_name = System.Text.Encoding.UTF8.GetBytes (host); extensions.Write ((short) 0x0000); // ExtensionType: server_name (0) extensions.Write ((short) (server_name.Length + 5)); // ServerNameList (length) extensions.Write ((short) (server_name.Length + 3)); // ServerName (length) diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs index fd1e2c5e206..0d4a4497200 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs @@ -291,10 +291,10 @@ namespace Mono.Security.Protocol.Tls } } - private void SafeReceiveRecord (Stream s) + private void SafeReceiveRecord (Stream s, bool ignoreEmpty = false) { byte[] record = this.protocol.ReceiveRecord (s); - if ((record == null) || (record.Length == 0)) { + if (!ignoreEmpty && ((record == null) || (record.Length == 0))) { throw new TlsException ( AlertDescription.HandshakeFailiure, "The server stopped the handshake."); @@ -308,8 +308,8 @@ namespace Mono.Security.Protocol.Tls // Read server response while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone) { - // Read next record - SafeReceiveRecord (this.innerStream); + // Read next record (skip empty, e.g. warnings alerts) + SafeReceiveRecord (this.innerStream, true); // special case for abbreviated handshake where no ServerHelloDone is sent from the server if (this.context.AbbreviatedHandshake && (this.context.LastHandshakeMsg == HandshakeType.ServerHello)) diff --git a/mcs/class/Mono.Security/Mono.Security.dll.sources b/mcs/class/Mono.Security/Mono.Security.dll.sources index f38e35e06ab..e6a36298cdf 100644 --- a/mcs/class/Mono.Security/Mono.Security.dll.sources +++ b/mcs/class/Mono.Security/Mono.Security.dll.sources @@ -66,7 +66,9 @@ ./Mono.Security.Cryptography/TlsHMAC.cs ./Mono.Security.Cryptography/MD5SHA1.cs ./Mono.Security.Protocol.Ntlm/ChallengeResponse.cs +./Mono.Security.Protocol.Ntlm/ChallengeResponse2.cs ./Mono.Security.Protocol.Ntlm/MessageBase.cs +./Mono.Security.Protocol.Ntlm/NtlmAuthLevel.cs ./Mono.Security.Protocol.Ntlm/NtlmFlags.cs ./Mono.Security.Protocol.Ntlm/Type1Message.cs ./Mono.Security.Protocol.Ntlm/Type2Message.cs diff --git a/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/MessageBaseTest.cs b/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/MessageBaseTest.cs index 2421612e4b8..7164640be9b 100644 --- a/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/MessageBaseTest.cs +++ b/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/MessageBaseTest.cs @@ -23,7 +23,7 @@ namespace MonoTests.Mono.Security.Protocol.Ntlm { [ExpectedException (typeof (ArgumentNullException))] public void Decode_Null () { - Type3Message msg = new Type3Message (null); + Type3Message msg = new Type3Message ((byte[])null); } [Test] diff --git a/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/Type3MessageTest.cs b/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/Type3MessageTest.cs index 79bc2d9ca28..05ad02f25f3 100644 --- a/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/Type3MessageTest.cs +++ b/mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/Type3MessageTest.cs @@ -23,6 +23,12 @@ namespace MonoTests.Mono.Security.Protocol.Ntlm { static byte[] data1 = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x72, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x54, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x01, 0x82, 0x00, 0x00, 0x55, 0x00, 0x52, 0x00, 0x53, 0x00, 0x41, 0x00, 0x2d, 0x00, 0x4d, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x61, 0x00, 0x70, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x47, 0x00, 0x48, 0x00, 0x54, 0x00, 0x43, 0x00, 0x49, 0x00, 0x54, 0x00, 0x59, 0x00, 0xad, 0x87, 0xca, 0x6d, 0xef, 0xe3, 0x46, 0x85, 0xb9, 0xc4, 0x3c, 0x47, 0x7a, 0x8c, 0x42, 0xd6, 0x00, 0x66, 0x7d, 0x68, 0x92, 0xe7, 0xe8, 0x97, 0xe0, 0xe0, 0x0d, 0xe3, 0x10, 0x4a, 0x1b, 0xf2, 0x05, 0x3f, 0x07, 0xc7, 0xdd, 0xa8, 0x2d, 0x3c, 0x48, 0x9a, 0xe9, 0x89, 0xe1, 0xb0, 0x00, 0xd3 }; static byte[] data2 = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x82, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x44, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x53, 0x00, 0x54, 0x00, 0x41, 0x00, 0x54, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0xc3, 0x37, 0xcd, 0x5c, 0xbd, 0x44, 0xfc, 0x97, 0x82, 0xa6, 0x67, 0xaf, 0x6d, 0x42, 0x7c, 0x6d, 0xe6, 0x7c, 0x20, 0xc2, 0xd3, 0xe7, 0x7c, 0x56, 0x25, 0xa9, 0x8c, 0x1c, 0x31, 0xe8, 0x18, 0x47, 0x46, 0x6b, 0x29, 0xb2, 0xdf, 0x46, 0x80, 0xf3, 0x99, 0x58, 0xfb, 0x8c, 0x21, 0x3a, 0x9c, 0xc6 }; + + static Type3MessageTest () + { + // Explicitly select legacy-mode. + Type3Message.DefaultAuthLevel = NtlmAuthLevel.LM_and_NTLM; + } [Test] // Example for a password smaller than 8 characters - which implies a weak DES key @@ -44,8 +50,9 @@ namespace MonoTests.Mono.Security.Protocol.Ntlm { { Type3Message msg = new Type3Message (); msg.Challenge = nonce; - msg.Domain = "Ursa-Minor"; - msg.Host = "LightCity"; + // Type3Message now encodes domain and host case-sensitive. + msg.Domain = "URSA-MINOR"; + msg.Host = "LIGHTCITY"; msg.Password = "Beeblebrox"; msg.Username = "Zaphod"; AssertEquals ("Type", 3, msg.Type); diff --git a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcFilter.cs b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcFilter.cs index e205619f7db..fe250f48295 100644 --- a/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcFilter.cs +++ b/mcs/class/Novell.Directory.Ldap/Novell.Directory.Ldap.Rfc2251/RfcFilter.cs @@ -463,7 +463,7 @@ namespace Novell.Directory.Ldap.Rfc2251 // utf8Bytes = new System.String(ca).getBytes("UTF-8"); // copy utf8 encoded character into octets - Array.Copy((System.Array) SupportClass.ToByteArray(utf8Bytes), 0, (System.Array)SupportClass.ToByteArray( octets), iOctets, utf8Bytes.Length); + Array.Copy((System.Array) (utf8Bytes), 0, (System.Array) octets, iOctets, utf8Bytes.Length); iOctets = iOctets + utf8Bytes.Length; } escape = false; diff --git a/mcs/class/PEAPI/Metadata.cs b/mcs/class/PEAPI/Metadata.cs index fa2c360863a..b2bc01dbd60 100644 --- a/mcs/class/PEAPI/Metadata.cs +++ b/mcs/class/PEAPI/Metadata.cs @@ -55,6 +55,7 @@ namespace PEAPI { PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800, Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000, AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000, + Forwarder = 0x200000, VisibilityMask = 0x07 } /// @@ -2090,9 +2091,9 @@ namespace PEAPI { ExternClass externClass; internal ExternClassRef(TypeAttr attrs, string nsName, string name, - FileRef declFile, MetaData md) : base(nsName,name,md) + MetaDataElement declRef, MetaData md) : base(nsName,name,md) { - externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declFile); + externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declRef); metaData.AddToTable(MDTable.ExportedType,externClass); } diff --git a/mcs/class/PEAPI/PEAPI.cs b/mcs/class/PEAPI/PEAPI.cs index 0cb718cee34..ce259c0739b 100644 --- a/mcs/class/PEAPI/PEAPI.cs +++ b/mcs/class/PEAPI/PEAPI.cs @@ -753,6 +753,11 @@ namespace PEAPI { return modRef; } + public ClassRef AddExternClass(string name, TypeAttr attrs, MetaDataElement declRef) + { + return new ExternClassRef (attrs, null, name, declRef, metaData); + } + /// /// Add a "global" method to this module /// diff --git a/mcs/class/System.Configuration/System.Configuration/Configuration.cs b/mcs/class/System.Configuration/System.Configuration/Configuration.cs index f21ffa26a3d..a3f8dc924f4 100644 --- a/mcs/class/System.Configuration/System.Configuration/Configuration.cs +++ b/mcs/class/System.Configuration/System.Configuration/Configuration.cs @@ -356,6 +356,7 @@ namespace System.Configuration { section.ConfigHost = system.Host; group.AddChild (section); elementData [section] = sec; + sec.Configuration = this; } internal void CreateSectionGroup (SectionGroupInfo parentGroup, string name, ConfigurationSectionGroup sec) diff --git a/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs b/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs index 704bb4a88ec..0fe992c6d4a 100644 --- a/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs +++ b/mcs/class/System.Configuration/System.Configuration/ConfigurationElement.cs @@ -94,12 +94,12 @@ namespace System.Configuration } } - [MonoTODO] protected ContextInformation EvaluationContext { get { if (Configuration != null) return Configuration.EvaluationContext; - throw new NotImplementedException (); + throw new ConfigurationErrorsException ( + "This element is not currently associated with any context."); } } diff --git a/mcs/class/System.Configuration/System.Configuration/ConfigurationSection.cs b/mcs/class/System.Configuration/System.Configuration/ConfigurationSection.cs index 7b02a1a13aa..84723f85aa5 100644 --- a/mcs/class/System.Configuration/System.Configuration/ConfigurationSection.cs +++ b/mcs/class/System.Configuration/System.Configuration/ConfigurationSection.cs @@ -134,6 +134,7 @@ namespace System.Configuration { ConfigurationElement elem = (ConfigurationElement) Activator.CreateInstance (t); elem.Init (); + elem.Configuration = Configuration; if (IsReadOnly ()) elem.SetReadOnly (); return elem; diff --git a/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs b/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs index 1219fcd9992..07ce1da61d5 100644 --- a/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs +++ b/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs @@ -207,7 +207,7 @@ namespace System.Configuration public virtual Stream OpenStreamForWrite (string streamName, string templateStreamName, ref object writeContext) { string dir = Path.GetDirectoryName (streamName); - if (!Directory.Exists (dir)) + if (!String.IsNullOrEmpty (dir) && !Directory.Exists (dir)) Directory.CreateDirectory (dir); return new FileStream (streamName, FileMode.Create, FileAccess.Write); } diff --git a/mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs b/mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs index d6e06cd3e89..d47ce4de912 100644 --- a/mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs +++ b/mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs @@ -61,6 +61,18 @@ namespace MonoTests.System.Configuration { if (Directory.Exists (tempFolder)) Directory.Delete (tempFolder, true); } + + static string DotNetVersion { + get { +#if NET_4_5 + return "net_4_5"; +#elif NET_4_0 + return "net_4_0"; +#else + return "net_2_0"; +#endif + } + } [Test] // OpenExeConfiguration (ConfigurationUserLevel) [Category ("NotWorking")] // bug #323622 @@ -145,12 +157,8 @@ namespace MonoTests.System.Configuration { FileInfo fi = new FileInfo (config.FilePath); #if TARGET_JVM Assert.AreEqual ("nunit-console.jar.config", fi.Name); -#elif NET_4_5 - Assert.AreEqual ("System.Configuration_test_net_4_5.dll.config", fi.Name); -#elif NET_4_0 - Assert.AreEqual ("System.Configuration_test_net_4_0.dll.config", fi.Name); #else - Assert.AreEqual ("System.Configuration_test_net_2_0.dll.config", fi.Name); + Assert.AreEqual ("System.Configuration_test_" + DotNetVersion + ".dll.config", fi.Name); #endif } @@ -263,8 +271,9 @@ namespace MonoTests.System.Configuration { public void exePath_UserLevelNone () { string basedir = AppDomain.CurrentDomain.BaseDirectory; - SysConfig config = ConfigurationManager.OpenExeConfiguration("System.Configuration_test_net_2_0.dll.mdb"); - Assert.AreEqual (Path.Combine (basedir, "System.Configuration_test_net_2_0.dll.mdb.config"), config.FilePath); + string name = "System.Configuration_test_" + DotNetVersion + ".dll"; + SysConfig config = ConfigurationManager.OpenExeConfiguration (name); + Assert.AreEqual (Path.Combine (basedir, name + ".config"), config.FilePath); } [Test] @@ -396,7 +405,7 @@ namespace MonoTests.System.Configuration { Console.WriteLine("null exe application config path: {0}", config.FilePath); FileInfo fi = new FileInfo (config.FilePath); - Assert.AreEqual ("System.Configuration_test_net_2_0.dll.config", fi.Name); + Assert.AreEqual ("System.Configuration_test_" + DotNetVersion + ".dll.config", fi.Name); #endif } @@ -411,7 +420,7 @@ namespace MonoTests.System.Configuration { #if TARGET_JVM Assert.AreEqual("System.Configuration.Test20.jar.config", fi.Name); #else - Assert.AreEqual ("System.Configuration_test_net_2_0.dll.config", fi.Name); + Assert.AreEqual ("System.Configuration_test_" + DotNetVersion + ".dll.config", fi.Name); #endif } @@ -486,6 +495,86 @@ namespace MonoTests.System.Configuration { Assert.IsNotNull(section as TestSection); config.Sections.Remove(name); } + + [Test] + public void TestFileMap () + { + var name = Path.GetRandomFileName () + ".config"; + Assert.IsFalse (File.Exists (name)); + + try { + var map = new ExeConfigurationFileMap (); + map.ExeConfigFilename = name; + + var config = ConfigurationManager.OpenMappedExeConfiguration ( + map, ConfigurationUserLevel.None); + + config.Sections.Add ("testsection", new TestSection ()); + + config.Save (); + + Assert.IsTrue (File.Exists (name), "#1"); + Assert.IsTrue (File.Exists (Path.GetFullPath (name)), "#2"); + } finally { + File.Delete (name); + } + } + + [Test] + public void TestContext () + { + var config = ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.None); + const string name = "testsection"; + + // ensure not present + if (config.GetSection (name) != null) + config.Sections.Remove (name); + + var section = new TestContextSection (); + + // Can't access EvaluationContext .... + try { + section.TestContext (null); + Assert.Fail ("#1"); + } catch (ConfigurationException) { + ; + } + + // ... until it's been added to a section. + config.Sections.Add (name, section); + section.TestContext ("#2"); + + // Remove ... + config.Sections.Remove (name); + + // ... and it doesn't lose its context + section.TestContext (null); + } + + [Test] + public void TestContext2 () + { + var name = Path.GetRandomFileName () + ".config"; + Assert.IsFalse (File.Exists (name)); + + try { + var map = new ExeConfigurationFileMap (); + map.ExeConfigFilename = name; + + var config = ConfigurationManager.OpenMappedExeConfiguration ( + map, ConfigurationUserLevel.None); + + config.Sections.Add ("testsection", new TestSection ()); + config.Sections.Add ("testcontext", new TestContextSection ()); + + config.Save (); + + Assert.IsTrue (File.Exists (name), "#1"); + } finally { + File.Delete (name); + } + } + class TestSection : ConfigurationSection {} @@ -533,5 +622,12 @@ namespace MonoTests.System.Configuration { return ConfigurationManager.AppSettings [key]; } } + + class TestContextSection : ConfigurationSection { + public void TestContext (string label) + { + Assert.That (EvaluationContext != null, label); + } + } } } diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs index 9baf52c3705..c4f9a6624d6 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs @@ -199,7 +199,7 @@ namespace System.IO.MemoryMappedFiles } - [DllImport("kernel32.dll", SetLastError = true)] + [DllImport("kernel32", SetLastError = true)] static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags); static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h) { diff --git a/mcs/class/System.Core/System.Linq.Expressions/BinaryExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/BinaryExpression.cs index 569299e8fbd..143f57513f4 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/BinaryExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/BinaryExpression.cs @@ -97,6 +97,7 @@ namespace System.Linq.Expressions { this.is_lifted = is_lifted; } +#if !FULL_AOT_RUNTIME void EmitArrayAccess (EmitContext ec) { left.Emit (ec); @@ -768,5 +769,6 @@ namespace System.Linq.Expressions { throw new NotSupportedException (this.NodeType.ToString ()); } } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/ConditionalExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/ConditionalExpression.cs index b9286535bc1..6d6d5dd60ec 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/ConditionalExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/ConditionalExpression.cs @@ -57,6 +57,7 @@ namespace System.Linq.Expressions { this.if_false = if_false; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { var ig = ec.ig; @@ -74,5 +75,6 @@ namespace System.Linq.Expressions { ig.MarkLabel (end_target); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs index dd45bdc967c..38a7b3cab66 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/ConstantExpression.cs @@ -50,6 +50,7 @@ namespace System.Linq.Expressions { this.value = value; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { if (Type.IsNullable ()) { @@ -190,5 +191,6 @@ namespace System.Linq.Expressions { emit (ec); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/ElementInit.cs b/mcs/class/System.Core/System.Linq.Expressions/ElementInit.cs index 0880f12f770..2069927b306 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/ElementInit.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/ElementInit.cs @@ -57,6 +57,7 @@ namespace System.Linq.Expressions { return ExpressionPrinter.ToString (this); } +#if !FULL_AOT_RUNTIME void EmitPopIfNeeded (EmitContext ec) { if (add_method.ReturnType == typeof (void)) @@ -70,5 +71,6 @@ namespace System.Linq.Expressions { ec.EmitCall (local, arguments, add_method); EmitPopIfNeeded (ec); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/EmitContext.cs b/mcs/class/System.Core/System.Linq.Expressions/EmitContext.cs index dd9934218b2..a43b87f728b 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/EmitContext.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/EmitContext.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Collections.ObjectModel; using System.Collections.Generic; @@ -606,3 +607,4 @@ namespace System.Linq.Expressions { } } } +#endif diff --git a/mcs/class/System.Core/System.Linq.Expressions/Expression.cs b/mcs/class/System.Core/System.Linq.Expressions/Expression.cs index ebc27e05457..bfe939a5cb0 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/Expression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/Expression.cs @@ -2268,9 +2268,11 @@ namespace System.Linq.Expressions { // This method must be overwritten by derived classes to // compile the expression // +#if !FULL_AOT_RUNTIME internal virtual void Emit (EmitContext ec) { throw new NotImplementedException (String.Format ("Emit method is not implemented in expression type {0}", GetType ())); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/InvocationExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/InvocationExpression.cs index 13994a13202..ad12dc38460 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/InvocationExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/InvocationExpression.cs @@ -53,9 +53,11 @@ namespace System.Linq.Expressions { this.arguments = arguments; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { ec.EmitCall (expression, arguments, expression.Type.GetInvokeMethod ()); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/LambdaExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/LambdaExpression.cs index 96d3ed81711..92a40c6d4b7 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/LambdaExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/LambdaExpression.cs @@ -55,6 +55,7 @@ namespace System.Linq.Expressions { this.parameters = parameters; } +#if !FULL_AOT_RUNTIME void EmitPopIfNeeded (EmitContext ec) { if (GetReturnType () == typeof (void) && body.Type != typeof (void)) @@ -72,6 +73,7 @@ namespace System.Linq.Expressions { EmitPopIfNeeded (ec); ec.ig.Emit (OpCodes.Ret); } +#endif internal Type GetReturnType () { diff --git a/mcs/class/System.Core/System.Linq.Expressions/ListInitExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/ListInitExpression.cs index 30915a89dc3..517ad39a72d 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/ListInitExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/ListInitExpression.cs @@ -53,11 +53,13 @@ namespace System.Linq.Expressions { this.initializers = initializers; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { var local = ec.EmitStored (new_expression); ec.EmitCollection (initializers, local); ec.EmitLoad (local); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberAssignment.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberAssignment.cs index f62acfb2ff5..cf581054568 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberAssignment.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberAssignment.cs @@ -47,6 +47,7 @@ namespace System.Linq.Expressions { this.expression = expression; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec, LocalBuilder local) { this.Member.OnFieldOrProperty ( @@ -71,5 +72,6 @@ namespace System.Linq.Expressions { expression.Emit (ec); ec.EmitCall (setter); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberBinding.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberBinding.cs index 5187fa551f1..bf0c6835c3f 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberBinding.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberBinding.cs @@ -56,6 +56,7 @@ namespace System.Linq.Expressions { return ExpressionPrinter.ToString (this); } +#if !FULL_AOT_RUNTIME internal abstract void Emit (EmitContext ec, LocalBuilder local); internal LocalBuilder EmitLoadMember (EmitContext ec, LocalBuilder local) @@ -86,5 +87,6 @@ namespace System.Linq.Expressions { ec.ig.Emit (OpCodes.Stloc, store); return store; } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberExpression.cs index 91a6aa0c1a8..1a0255f4ea7 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberExpression.cs @@ -52,6 +52,7 @@ namespace System.Linq.Expressions { this.member = member; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { member.OnFieldOrProperty ( @@ -76,5 +77,6 @@ namespace System.Linq.Expressions { } else ec.ig.Emit (OpCodes.Ldsfld, field); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberInitExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberInitExpression.cs index 59b71baeef3..ed30e9c2fb9 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberInitExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberInitExpression.cs @@ -52,11 +52,13 @@ namespace System.Linq.Expressions { this.bindings = bindings; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { var local = ec.EmitStored (new_expression); ec.EmitCollection (bindings, local); ec.EmitLoad (local); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberListBinding.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberListBinding.cs index 03b7e67da63..3c320e63e30 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberListBinding.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberListBinding.cs @@ -47,6 +47,7 @@ namespace System.Linq.Expressions { this.initializers = initializers; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec, LocalBuilder local) { var member = EmitLoadMember (ec, local); @@ -54,5 +55,6 @@ namespace System.Linq.Expressions { foreach (var initializer in initializers) initializer.Emit (ec, member); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MemberMemberBinding.cs b/mcs/class/System.Core/System.Linq.Expressions/MemberMemberBinding.cs index 9eb0c515d9d..ec10de5c526 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MemberMemberBinding.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MemberMemberBinding.cs @@ -47,6 +47,7 @@ namespace System.Linq.Expressions { this.bindings = bindings; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec, LocalBuilder local) { var member = EmitLoadMember (ec, local); @@ -54,5 +55,6 @@ namespace System.Linq.Expressions { foreach (var binding in bindings) binding.Emit (ec, member); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/MethodCallExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/MethodCallExpression.cs index 02718ffa055..7f898689c0a 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/MethodCallExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/MethodCallExpression.cs @@ -66,9 +66,11 @@ namespace System.Linq.Expressions { this.arguments = arguments; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { ec.EmitCall (obj, arguments, method); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/NewArrayExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/NewArrayExpression.cs index b952b8c0057..c30bec70537 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/NewArrayExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/NewArrayExpression.cs @@ -48,6 +48,7 @@ namespace System.Linq.Expressions { this.expressions = expressions; } +#if !FULL_AOT_RUNTIME void EmitNewArrayInit (EmitContext ec, Type type) { var size = expressions.Count; @@ -107,5 +108,6 @@ namespace System.Linq.Expressions { throw new NotSupportedException (); } } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/NewExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/NewExpression.cs index 8e6673c616c..005d17569ec 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/NewExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/NewExpression.cs @@ -65,6 +65,7 @@ namespace System.Linq.Expressions { this.members = members; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { var ig = ec.ig; @@ -90,6 +91,7 @@ namespace System.Linq.Expressions { } else ig.Emit (OpCodes.Newobj, constructor ?? GetDefaultConstructor (type)); } +#endif static ConstructorInfo GetDefaultConstructor (Type type) { diff --git a/mcs/class/System.Core/System.Linq.Expressions/ParameterExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/ParameterExpression.cs index 651f9a90b94..94bd0ea4475 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/ParameterExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/ParameterExpression.cs @@ -46,6 +46,7 @@ namespace System.Linq.Expressions { this.name = name; } +#if !FULL_AOT_RUNTIME void EmitLocalParameter (EmitContext ec, int position) { ec.ig.Emit (OpCodes.Ldarg, position); @@ -82,5 +83,6 @@ namespace System.Linq.Expressions { throw new InvalidOperationException ("Parameter out of scope"); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/TypeBinaryExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/TypeBinaryExpression.cs index 4463e4e8b29..2629c96c4f2 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/TypeBinaryExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/TypeBinaryExpression.cs @@ -51,6 +51,7 @@ namespace System.Linq.Expressions { this.type_operand = type_operand; } +#if !FULL_AOT_RUNTIME internal override void Emit (EmitContext ec) { if (expression.Type == typeof (void)) { @@ -63,5 +64,6 @@ namespace System.Linq.Expressions { ec.ig.Emit (OpCodes.Ldnull); ec.ig.Emit (OpCodes.Cgt_Un); } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs b/mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs index 11e6240afca..4f6f9cb890d 100644 --- a/mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs +++ b/mcs/class/System.Core/System.Linq.Expressions/UnaryExpression.cs @@ -68,6 +68,7 @@ namespace System.Linq.Expressions { this.is_lifted = is_lifted; } +#if !FULL_AOT_RUNTIME void EmitArrayLength (EmitContext ec) { operand.Emit (ec); @@ -431,5 +432,6 @@ namespace System.Linq.Expressions { throw new NotImplementedException (this.NodeType.ToString ()); } } +#endif } } diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryBaseNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryBaseNode.cs index 37cc578c316..99879ac4431 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryBaseNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryBaseNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Threading.Tasks; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryCastNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryCastNode.cs index 4dbb49b23b4..1fa3f407e38 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryCastNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryCastNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Threading.Tasks; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryChildNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryChildNode.cs index 646d7e76715..ab5043a5cc3 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryChildNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryChildNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; namespace System.Linq.Parallel.QueryNodes diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryConcatNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryConcatNode.cs index e09dfbf9543..2942b5162b8 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryConcatNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryConcatNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs index c3b766eaa2a..7d86b63f9e4 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs index 87d870b4deb..69dbbb1bd18 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; @@ -69,7 +69,7 @@ namespace System.Linq.Parallel.QueryNodes internal IEnumerable> GetGroupedElements () { - return GetStore ().Select (e => (IGrouping)new ConcurrentGrouping (e.Key, e.Value)); + return (IEnumerable>)GetStore ().Select (e => (IGrouping)new ConcurrentGrouping (e.Key, e.Value)); } internal ConcurrentDictionary> GetStore () diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs index 223783fa5fc..6918086e5b8 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryJoinNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryJoinNode.cs index 79ed83eb11c..61b9162e1f3 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryJoinNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryJoinNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryMuxNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryMuxNode.cs index 4a320c78935..6ca3ab0dd96 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryMuxNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryMuxNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOptionNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOptionNode.cs index a6c713e26b8..1a3eb63628c 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOptionNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOptionNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs index d3b7caeeb9b..1dba782eff6 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs index 4b4b75daf3f..047fd9ac227 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs @@ -23,7 +23,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs index 388ae952517..266b6803580 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; namespace System.Linq.Parallel.QueryNodes diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryReverseNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryReverseNode.cs index c7128658a43..982abd3cc53 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryReverseNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryReverseNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Threading; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs index 815cb5fc9f6..2d7d0d1115c 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectNode.cs index 78ffd83af20..50daf099ae6 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySelectNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySetNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySetNode.cs index 7e3d18be232..68a531a3ae2 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySetNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QuerySetNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStartNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStartNode.cs index f1fd930ee05..8bffdfad705 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStartNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStartNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStreamNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStreamNode.cs index cd1700f33e0..8dab7cfe870 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStreamNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryStreamNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Threading.Tasks; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryWhereNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryWhereNode.cs index 8d9c9ad7f5f..fe9ca8a90ed 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryWhereNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryWhereNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Threading; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryZipNode.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryZipNode.cs index 9b9b475ac68..124027b6b04 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryZipNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/QueryZipNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Linq; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/SetInclusion.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/SetInclusion.cs index 8baf43450bc..63f043d2f1e 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/SetInclusion.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/SetInclusion.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/WrapHelper.cs b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/WrapHelper.cs index b3239e4165f..4d51db0a765 100644 --- a/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/WrapHelper.cs +++ b/mcs/class/System.Core/System.Linq.Parallel.QueryNodes/WrapHelper.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/AggregationList.cs b/mcs/class/System.Core/System.Linq.Parallel/AggregationList.cs index 0d403ed3a4c..225fcac9a9c 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/AggregationList.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/AggregationList.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ConcurrentGrouping.cs b/mcs/class/System.Core/System.Linq.Parallel/ConcurrentGrouping.cs index 3864b48a531..7e666842922 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ConcurrentGrouping.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ConcurrentGrouping.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ConcurrentLookup.cs b/mcs/class/System.Core/System.Linq.Parallel/ConcurrentLookup.cs index 0cf258e51fa..c355d955e1b 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ConcurrentLookup.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ConcurrentLookup.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; @@ -109,7 +109,7 @@ namespace System.Linq.Parallel IEnumerator> GetEnumeratorInternal () { - return dictionary.Select ((pair) => new ConcurrentGrouping (pair.Key, pair.Value)).GetEnumerator (); + return (IEnumerator>) dictionary.Select ((pair) => new ConcurrentGrouping (pair.Key, pair.Value)).GetEnumerator (); } } } diff --git a/mcs/class/System.Core/System.Linq.Parallel/INodeVisitor.cs b/mcs/class/System.Core/System.Linq.Parallel/INodeVisitor.cs index 5b68a4425a5..90bbee4f174 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/INodeVisitor.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/INodeVisitor.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq.Parallel.QueryNodes; diff --git a/mcs/class/System.Core/System.Linq.Parallel/IVisitableNode.cs b/mcs/class/System.Core/System.Linq.Parallel/IVisitableNode.cs index 013dc53598a..9be102c0c03 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/IVisitableNode.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/IVisitableNode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; namespace System.Linq.Parallel diff --git a/mcs/class/System.Core/System.Linq.Parallel/OrderingEnumerator.cs b/mcs/class/System.Core/System.Linq.Parallel/OrderingEnumerator.cs index 6012f790493..40023031dcc 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/OrderingEnumerator.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/OrderingEnumerator.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs b/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs index 96a5fe1f8e3..5f78b5165d2 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ParallelExecuter.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Threading.Tasks; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ParallelPartitioner.cs b/mcs/class/System.Core/System.Linq.Parallel/ParallelPartitioner.cs index e9bf2f8b4e2..e9a61cf9110 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ParallelPartitioner.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ParallelPartitioner.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ParallelQueryEnumerator.cs b/mcs/class/System.Core/System.Linq.Parallel/ParallelQueryEnumerator.cs index a3d17520c62..c30266abd18 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ParallelQueryEnumerator.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ParallelQueryEnumerator.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ParallelQuickSort.cs b/mcs/class/System.Core/System.Linq.Parallel/ParallelQuickSort.cs index cb46dcc86ae..29f357e5a6f 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ParallelQuickSort.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ParallelQuickSort.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Linq; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/QueryCheckerVisitor.cs b/mcs/class/System.Core/System.Linq.Parallel/QueryCheckerVisitor.cs index 1bf8f6b3cc6..c0ce24e0f1c 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/QueryCheckerVisitor.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/QueryCheckerVisitor.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Linq.Parallel.QueryNodes; diff --git a/mcs/class/System.Core/System.Linq.Parallel/QueryIsOrderedVisitor.cs b/mcs/class/System.Core/System.Linq.Parallel/QueryIsOrderedVisitor.cs index 01cab21f68e..debc0d8af15 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/QueryIsOrderedVisitor.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/QueryIsOrderedVisitor.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Linq.Parallel.QueryNodes; diff --git a/mcs/class/System.Core/System.Linq.Parallel/QueryOptions.cs b/mcs/class/System.Core/System.Linq.Parallel/QueryOptions.cs index 7ca9a8586d3..9ec67ef6d4a 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/QueryOptions.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/QueryOptions.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; diff --git a/mcs/class/System.Core/System.Linq.Parallel/RangeList.cs b/mcs/class/System.Core/System.Linq.Parallel/RangeList.cs index 5a8985bbe69..cd58ed8bacc 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/RangeList.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/RangeList.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel/RepeatList.cs b/mcs/class/System.Core/System.Linq.Parallel/RepeatList.cs index e2c99d2ed57..b506897b375 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/RepeatList.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/RepeatList.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel/ReverseList.cs b/mcs/class/System.Core/System.Linq.Parallel/ReverseList.cs index 909de501bda..628d925917f 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/ReverseList.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/ReverseList.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System.Linq; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq.Parallel/StripPartitioner.cs b/mcs/class/System.Core/System.Linq.Parallel/StripPartitioner.cs index 8b4c41210c9..62be137a81c 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/StripPartitioner.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/StripPartitioner.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Linq.Parallel/TemporaryArea.cs b/mcs/class/System.Core/System.Linq.Parallel/TemporaryArea.cs index b8be6abc055..6ebc18e9732 100644 --- a/mcs/class/System.Core/System.Linq.Parallel/TemporaryArea.cs +++ b/mcs/class/System.Core/System.Linq.Parallel/TemporaryArea.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq/Enumerable.cs b/mcs/class/System.Core/System.Linq/Enumerable.cs index 0f9b717b4af..73e5006211b 100644 --- a/mcs/class/System.Core/System.Linq/Enumerable.cs +++ b/mcs/class/System.Core/System.Linq/Enumerable.cs @@ -45,9 +45,11 @@ namespace System.Linq Throw } +#if !FULL_AOT_RUNTIME static class PredicateOf { public static readonly Func Always = (t) => true; } +#endif static class Function { public static readonly Func Identity = (t) => t; @@ -71,7 +73,7 @@ namespace System.Linq // if zero elements and treat the first element differently using (var enumerator = source.GetEnumerator ()) { if (!enumerator.MoveNext ()) - throw new InvalidOperationException ("No elements in source list"); + throw EmptySequence (); TSource folded = enumerator.Current; while (enumerator.MoveNext ()) @@ -171,7 +173,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / (double) count; } @@ -186,7 +188,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / (double) count; } @@ -201,7 +203,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -216,7 +218,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -231,7 +233,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -379,7 +381,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / (double) count; } @@ -416,7 +418,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / (double) count; } @@ -454,7 +456,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -493,7 +495,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -530,7 +532,7 @@ namespace System.Linq count++; } if (count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); return total / count; } @@ -811,7 +813,7 @@ namespace System.Linq return element; if (fallback == Fallback.Throw) - throw new InvalidOperationException (); + throw NoMatchingElement (); return default (TSource); } @@ -831,7 +833,7 @@ namespace System.Linq } } - throw new InvalidOperationException ("The source sequence is empty"); + throw EmptySequence (); } public static TSource First (this IEnumerable source, Func predicate) @@ -849,7 +851,15 @@ namespace System.Linq { Check.Source (source); +#if !FULL_AOT_RUNTIME return source.First (PredicateOf.Always, Fallback.Default); +#else + // inline the code to reduce dependency o generic causing AOT errors on device (e.g. bug #3285) + foreach (var element in source) + return element; + + return default (TSource); +#endif } public static TSource FirstOrDefault (this IEnumerable source, Func predicate) @@ -1191,7 +1201,7 @@ namespace System.Linq return item; if (fallback == Fallback.Throw) - throw new InvalidOperationException (); + throw NoMatchingElement (); return item; } @@ -1202,14 +1212,29 @@ namespace System.Linq var collection = source as ICollection; if (collection != null && collection.Count == 0) - throw new InvalidOperationException (); + throw EmptySequence (); var list = source as IList; if (list != null) return list [list.Count - 1]; +#if !FULL_AOT_RUNTIME return source.Last (PredicateOf.Always, Fallback.Throw); - } +#else + var empty = true; + var item = default (TSource); + + foreach (var element in source) { + item = element; + empty = false; + } + + if (!empty) + return item; + + throw EmptySequence (); +#endif + } public static TSource Last (this IEnumerable source, Func predicate) { @@ -1230,7 +1255,22 @@ namespace System.Linq if (list != null) return list.Count > 0 ? list [list.Count - 1] : default (TSource); +#if !FULL_AOT_RUNTIME return source.Last (PredicateOf.Always, Fallback.Default); +#else + var empty = true; + var item = default (TSource); + + foreach (var element in source) { + item = element; + empty = false; + } + + if (!empty) + return item; + + return item; +#endif } public static TSource LastOrDefault (this IEnumerable source, Func predicate) @@ -1289,7 +1329,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence(); return max; } @@ -1304,7 +1344,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return max; } @@ -1319,7 +1359,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return max; } @@ -1334,7 +1374,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return max; } @@ -1349,7 +1389,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return max; } @@ -1487,7 +1527,7 @@ namespace System.Linq max = element; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); } return max; } @@ -1503,7 +1543,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return max; } @@ -1518,7 +1558,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return max; } @@ -1533,7 +1573,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return max; } @@ -1548,7 +1588,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return max; } @@ -1563,7 +1603,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return max; } @@ -1576,7 +1616,7 @@ namespace System.Linq } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return initValue; } @@ -1709,7 +1749,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return min; } @@ -1724,7 +1764,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return min; } @@ -1739,7 +1779,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return min; } @@ -1754,7 +1794,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return min; } @@ -1769,7 +1809,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); return min; } @@ -1906,7 +1946,7 @@ namespace System.Linq min = element; } if (empty) - throw new InvalidOperationException (); + throw EmptySequence (); } return min; } @@ -1922,7 +1962,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return min; } @@ -1937,7 +1977,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return min; } @@ -1952,7 +1992,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return min; } @@ -1967,7 +2007,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return min; } @@ -1982,7 +2022,7 @@ namespace System.Linq empty = false; } if (empty) - throw new InvalidOperationException (); + throw NoMatchingElement (); return min; } @@ -2327,14 +2367,14 @@ namespace System.Linq continue; if (found) - throw new InvalidOperationException (); + throw MoreThanOneMatchingElement (); found = true; item = element; } if (!found && fallback == Fallback.Throw) - throw new InvalidOperationException (); + throw NoMatchingElement (); return item; } @@ -2343,8 +2383,26 @@ namespace System.Linq { Check.Source (source); +#if !FULL_AOT_RUNTIME return source.Single (PredicateOf.Always, Fallback.Throw); - } +#else + var found = false; + var item = default (TSource); + + foreach (var element in source) { + if (found) + throw MoreThanOneElement (); + + found = true; + item = element; + } + + if (!found) + throw NoMatchingElement (); + + return item; +#endif + } public static TSource Single (this IEnumerable source, Func predicate) { @@ -2361,8 +2419,23 @@ namespace System.Linq { Check.Source (source); +#if !FULL_AOT_RUNTIME return source.Single (PredicateOf.Always, Fallback.Default); - } +#else + var found = false; + var item = default (TSource); + + foreach (var element in source) { + if (found) + throw MoreThanOneMatchingElement (); + + found = true; + item = element; + } + + return item; +#endif + } public static TSource SingleOrDefault (this IEnumerable source, Func predicate) { @@ -2762,6 +2835,12 @@ namespace System.Linq { Check.SourceAndKeySelector (source, keySelector); +#if FULL_AOT_RUNTIME + var oe = source as OrderedEnumerable ; + if (oe != null) + return oe.CreateOrderedEnumerable (keySelector, comparer, false); +#endif + return source.CreateOrderedEnumerable (keySelector, comparer, false); } @@ -2780,6 +2859,11 @@ namespace System.Linq { Check.SourceAndKeySelector (source, keySelector); +#if FULL_AOT_RUNTIME + var oe = source as OrderedEnumerable ; + if (oe != null) + return oe.CreateOrderedEnumerable (keySelector, comparer, true); +#endif return source.CreateOrderedEnumerable (keySelector, comparer, true); } @@ -2878,7 +2962,7 @@ namespace System.Linq public static ILookup ToLookup (this IEnumerable source, Func keySelector, IEqualityComparer comparer) { - return ToLookup (source, keySelector, element => element, comparer); + return ToLookup (source, keySelector, Function.Identity, comparer); } public static ILookup ToLookup (this IEnumerable source, @@ -3061,5 +3145,26 @@ namespace System.Linq return new ReadOnlyCollection (source.ToArray ()); } + + #region Exception helpers + + static Exception EmptySequence () + { + return new InvalidOperationException (Locale.GetText ("Sequence contains no elements")); + } + static Exception NoMatchingElement () + { + return new InvalidOperationException (Locale.GetText ("Sequence contains no matching element")); + } + static Exception MoreThanOneElement () + { + return new InvalidOperationException (Locale.GetText ("Sequence contains more than one element")); + } + static Exception MoreThanOneMatchingElement () + { + return new InvalidOperationException (Locale.GetText ("Sequence contains more than one matching element")); + } + + #endregion } } diff --git a/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs b/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs index 842555c4c4b..1bd7949c8c9 100644 --- a/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs +++ b/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs b/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs index 44b45c35820..9d093826f15 100644 --- a/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs +++ b/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; using System.Collections; diff --git a/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs b/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs index 7b6687cfd74..888824959b5 100644 --- a/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs +++ b/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; namespace System.Linq diff --git a/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs b/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs index f40defc99f0..6073516aa69 100644 --- a/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs +++ b/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; namespace System.Linq diff --git a/mcs/class/System.Core/System.Linq/ParallelQuery.cs b/mcs/class/System.Core/System.Linq/ParallelQuery.cs index c5ea95e41b0..4bf5922d83f 100644 --- a/mcs/class/System.Core/System.Linq/ParallelQuery.cs +++ b/mcs/class/System.Core/System.Linq/ParallelQuery.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; diff --git a/mcs/class/System.Core/System.Linq/Queryable.cs b/mcs/class/System.Core/System.Linq/Queryable.cs index bfc4b34f4e4..e9b98cca9e1 100644 --- a/mcs/class/System.Core/System.Linq/Queryable.cs +++ b/mcs/class/System.Core/System.Linq/Queryable.cs @@ -1603,7 +1603,7 @@ namespace System.Linq { #endregion -#if NET_4_0 || MOONLIGHT +#if NET_4_0 || MOONLIGHT || MOBILE #region Zip public static IQueryable Zip (this IQueryable source1, IEnumerable source2, Expression> resultSelector) diff --git a/mcs/class/System.Core/System.Linq/QuickSort.cs b/mcs/class/System.Core/System.Linq/QuickSort.cs index 553b94b452c..729c080c639 100644 --- a/mcs/class/System.Core/System.Linq/QuickSort.cs +++ b/mcs/class/System.Core/System.Linq/QuickSort.cs @@ -65,7 +65,7 @@ namespace System.Linq { // Then sorts the elements according to the collected // key values and the selected ordering - Array.Sort (indexes, elements, context); + Array.Sort (indexes, context); } public static IEnumerable Sort (IEnumerable source, SortContext context) @@ -75,7 +75,7 @@ namespace System.Linq { sorter.PerformSort (); for (int i = 0; i < sorter.elements.Length; i++) - yield return sorter.elements [i]; + yield return sorter.elements [sorter.indexes [i]]; } } } diff --git a/mcs/class/System.Core/System.Runtime.CompilerServices/ExecutionScope.cs b/mcs/class/System.Core/System.Runtime.CompilerServices/ExecutionScope.cs index ef063be4974..b64fd4e55ae 100644 --- a/mcs/class/System.Core/System.Runtime.CompilerServices/ExecutionScope.cs +++ b/mcs/class/System.Core/System.Runtime.CompilerServices/ExecutionScope.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Linq.Expressions; @@ -96,3 +97,4 @@ namespace System.Runtime.CompilerServices { } } } +#endif diff --git a/mcs/class/System.Core/System.Security.Cryptography/Aes.cs b/mcs/class/System.Core/System.Security.Cryptography/Aes.cs index 7f2272fdd2e..cb2ddbc93fa 100644 --- a/mcs/class/System.Core/System.Security.Cryptography/Aes.cs +++ b/mcs/class/System.Core/System.Security.Cryptography/Aes.cs @@ -56,7 +56,17 @@ namespace System.Security.Cryptography { public static new Aes Create () { +#if FULL_AOT_RUNTIME + // The Aes base class was moved from System.Core to mscorlib - so we can't just return a new AesCryptoServiceProvider instance + // note: the linker is aware of this condition + return (Aes) Activator.CreateInstance (Type.GetType ("System.Security.Cryptography.AesCryptoServiceProvider, " + Consts.AssemblySystem_Core)); +#elif MOBILE + // there was a mixup in the MOBILE profile, to be compatible with Silverlight it's + // AesManaged that should have been provided, not AesCryptoServiceProvider + return Create ("System.Security.Cryptography.AesCryptoServiceProvider, " + Consts.AssemblySystem_Core); +#else return Create ("System.Security.Cryptography.AesManaged, " + Consts.AssemblySystem_Core); +#endif } public static new Aes Create (string algorithmName) @@ -68,7 +78,7 @@ namespace System.Security.Cryptography { { KeySizeValue = 256; BlockSizeValue = 128; -#if !NET_2_1 +#if !MOONLIGHT // Silverlight 2.0 only supports CBC mode (i.e. no feedback) FeedbackSizeValue = 128; #endif diff --git a/mcs/class/System.Core/System/TimeZoneInfo.cs b/mcs/class/System.Core/System/TimeZoneInfo.cs index f3a2a643b28..e60f8588296 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.cs @@ -382,7 +382,10 @@ namespace System } #endif #if MONODROID - return ZoneInfoDB.GetTimeZone (id); + var timeZoneInfo = ZoneInfoDB.GetTimeZone (id); + if (timeZoneInfo != null) + throw new TimeZoneNotFoundException (); + return timeZoneInfo; #else // Local requires special logic that already exists in the Local property (bug #326) if (id == "Local") diff --git a/mcs/class/System.Core/mobile_System.Core.dll.sources b/mcs/class/System.Core/mobile_System.Core.dll.sources index d2c2a348d5f..979c4e162e4 100644 --- a/mcs/class/System.Core/mobile_System.Core.dll.sources +++ b/mcs/class/System.Core/mobile_System.Core.dll.sources @@ -3,6 +3,7 @@ ../../build/common/MonoTODOAttribute.cs ../corlib/Mono.Security.Cryptography/CryptoTools.cs ../corlib/Mono.Security.Cryptography/SymmetricTransform.cs +../corlib/System.Collections.Concurrent.Partitioners/EnumerablePartitioner.cs Assembly/AssemblyInfo.cs System/Actions.cs System/Funcs.cs @@ -86,6 +87,7 @@ System.Linq.Parallel/RangeList.cs System.Linq.Parallel/RepeatList.cs System.Linq.Parallel/ReverseList.cs System.Linq.Parallel/StripPartitioner.cs +System.Linq.Parallel/TemporaryArea.cs System.Linq/EnumerableExecutor.cs System.Linq/EnumerableExecutor_T.cs System.Linq/EnumerableQuery.cs diff --git a/mcs/class/System.Reactive.Core/Makefile b/mcs/class/System.Reactive.Core/Makefile new file mode 100644 index 00000000000..1a09fb54bc4 --- /dev/null +++ b/mcs/class/System.Reactive.Core/Makefile @@ -0,0 +1,58 @@ +thisdir = class/System.Reactive.Core +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Core.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll + +ifeq (true, $(GENERATE_RESOURCES)) +LIB_MCS_FLAGS += /define:GENERATING_RESOURCES +endif + +RESX_RESOURCES = \ + Strings_Core.resources + +CLEAN_FILES += $(RESX_RESOURCES) + +RESOURCES = $(RESX_RESOURCES) + +PREBUILT = $(RESX_RESOURCES:=.prebuilt) + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Core.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make + +$(the_lib): $(RESOURCES) + +$(RESX_RESOURCES): %.resources: %.resx + $(RESGEN) $< || cp $@.prebuilt $@ + +$(PREBUILT): %.prebuilt: % + cp $* $@ + +dist-default: $(PREBUILT) + diff --git a/mcs/class/System.Reactive.Core/Strings_Core.resources.prebuilt b/mcs/class/System.Reactive.Core/Strings_Core.resources.prebuilt new file mode 100644 index 00000000000..1bde5849d06 Binary files /dev/null and b/mcs/class/System.Reactive.Core/Strings_Core.resources.prebuilt differ diff --git a/mcs/class/System.Reactive.Core/Strings_Core.resx b/mcs/class/System.Reactive.Core/Strings_Core.resx new file mode 100644 index 00000000000..253ca99b261 --- /dev/null +++ b/mcs/class/System.Reactive.Core/Strings_Core.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Using the Scheduler.{0} property is no longer supported due to refactoring of the API surface and elimination of platform-specific dependencies. Please include System.Reactive.PlatformServices for your target platform and use the {0}Scheduler type instead. If you're building a Windows Store app, notice some schedulers are no longer supported. Consider using Scheduler.Default instead. + + + OnCompleted notification doesn't have a value. + + + Disposable has already been assigned. + + + Failed to start monitoring system clock changes. + + + Heap is empty. + + + Observer has already terminated. + + + Reentrancy has been detected. + + + This scheduler operation has already been awaited. + Only on .NET 4.5 and above. + + \ No newline at end of file diff --git a/mcs/class/System.Reactive.Core/System.Reactive.Core.dll.sources b/mcs/class/System.Reactive.Core/System.Reactive.Core.dll.sources new file mode 100644 index 00000000000..257e51ff394 --- /dev/null +++ b/mcs/class/System.Reactive.Core/System.Reactive.Core.dll.sources @@ -0,0 +1,78 @@ +../../../external/rx/Rx.NET/System.Reactive.Core/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Core/InternalsVisibleTo.cs +../../../external/rx/Rx.NET/System.Reactive.Core/NamespaceDocs.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Observable.Extensions.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Observer.Extensions.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/AnonymousObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/AnonymousObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/AnonymousSafeObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/AsyncLock.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/CatchScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/ConcurrencyAbstractionLayer.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/ConcurrencyAbstractionLayer.Default.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Wrappers.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/DisableOptimizationsScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Services.Emulation.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/LocalScheduler.TimerQueue.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Services.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/CurrentThreadScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/ImmediateScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/LocalScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/ScheduledItem.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Async.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Recursive.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Scheduler.Simple.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/SchedulerDefaults.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/SchedulerOperation.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/SchedulerQueue.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/SchedulerWrapper.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Stopwatch.Default.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Synchronization.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Synchronization.ObserveOn.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/Synchronization.Synchronize.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/SynchronizationContextScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Concurrency/DefaultScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/AsyncLockObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/CheckedObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ConcurrentDictionary.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ConcurrentQueue.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Constants.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/AnonymousDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/BooleanDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/CancellationDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/CompositeDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/ContextDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/DefaultDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/Disposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/MultipleAssignmentDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/RefCountDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/ScheduledDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/SerialDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Disposables/SingleAssignmentDisposable.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/AutoDetachObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ExceptionServices.Default.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ExceptionServices.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/HostLifecycleService.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ImmutableList.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Lazy.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Observers.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/PlatformEnlightenmentProvider.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/PriorityQueue.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Producer.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/SafeObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/ScheduledObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Semaphore.Silverlight.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Semaphore.Xna.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Sink.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/Stubs.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/SynchronizationContextExtensions.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/SynchronizedObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/SystemClock.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Internal/SystemClock.Default.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Notification.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/ObservableBase.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/ObserverBase.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Reactive/Unit.cs +../../../external/rx/Rx.NET/System.Reactive.Core/Strings_Core.Generated.cs diff --git a/mcs/class/System.Reactive.Core/more_build_args b/mcs/class/System.Reactive.Core/more_build_args new file mode 100644 index 00000000000..f832406a175 --- /dev/null +++ b/mcs/class/System.Reactive.Core/more_build_args @@ -0,0 +1,4 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub +-resource:Strings_Core.resources,System.Reactive.Strings_Core.resources diff --git a/mcs/class/System.Reactive.Debugger/Makefile b/mcs/class/System.Reactive.Debugger/Makefile new file mode 100644 index 00000000000..24d6fa753aa --- /dev/null +++ b/mcs/class/System.Reactive.Debugger/Makefile @@ -0,0 +1,36 @@ +thisdir = class/System.Reactive.Debugger +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Debugger.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Debugger.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/System.Reactive.Debugger/System.Reactive.Debugger.dll.sources b/mcs/class/System.Reactive.Debugger/System.Reactive.Debugger.dll.sources new file mode 100644 index 00000000000..711f341c3e1 --- /dev/null +++ b/mcs/class/System.Reactive.Debugger/System.Reactive.Debugger.dll.sources @@ -0,0 +1,2 @@ +../../../external/rx/Rx.NET/System.Reactive.Debugger/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Debugger/Reactive/Linq/QueryDebugger.cs diff --git a/mcs/class/System.Reactive.Debugger/more_build_args b/mcs/class/System.Reactive.Debugger/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/System.Reactive.Debugger/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/System.Reactive.Experimental/Makefile b/mcs/class/System.Reactive.Experimental/Makefile new file mode 100644 index 00000000000..effbc887c81 --- /dev/null +++ b/mcs/class/System.Reactive.Experimental/Makefile @@ -0,0 +1,36 @@ +thisdir = class/System.Reactive.Experimental +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Experimental.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Experimental.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/System.Reactive.Experimental/System.Reactive.Experimental.dll.sources b/mcs/class/System.Reactive.Experimental/System.Reactive.Experimental.dll.sources new file mode 100644 index 00000000000..014a9c93f42 --- /dev/null +++ b/mcs/class/System.Reactive.Experimental/System.Reactive.Experimental.dll.sources @@ -0,0 +1,10 @@ +../../../external/rx/Rx.NET/System.Reactive.Experimental/ExperimentalAttribute.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/InternalsVisibleTo.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Internal/BinaryObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Linq/QbservableEx.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Linq/IQueryLanguageEx.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Linq/ObservableEx.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Linq/QbservableEx.Generated.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/Linq/QueryLanguageEx.cs +../../../external/rx/Rx.NET/System.Reactive.Experimental/Reactive/ListObservable.cs diff --git a/mcs/class/System.Reactive.Experimental/more_build_args b/mcs/class/System.Reactive.Experimental/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/System.Reactive.Experimental/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/System.Reactive.Interfaces/Makefile b/mcs/class/System.Reactive.Interfaces/Makefile new file mode 100644 index 00000000000..79ccee23fd4 --- /dev/null +++ b/mcs/class/System.Reactive.Interfaces/Makefile @@ -0,0 +1,33 @@ +thisdir = class/System.Reactive.Interfaces +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Interfaces.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Interfaces.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/System.Reactive.Interfaces/System.Reactive.Interfaces.dll.sources b/mcs/class/System.Reactive.Interfaces/System.Reactive.Interfaces.dll.sources new file mode 100644 index 00000000000..2ce2955ed3b --- /dev/null +++ b/mcs/class/System.Reactive.Interfaces/System.Reactive.Interfaces.dll.sources @@ -0,0 +1,24 @@ +../../../external/rx/Rx.NET/System.Reactive.Interfaces/AssemblyFileVersionAttribute.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/DateTimeOffset.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/IObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/IObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/NamespaceDocs.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/ISchedulerPeriodic.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/IStopwatchProvider.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/IScheduledItem.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/IScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/ISchedulerLongRunning.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Concurrency/IStopwatch.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Disposables/ICancelable.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/IEventPattern.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/IEventPatternSource.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/IEventSource.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/IObserver.Result.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Linq/IGroupedObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Linq/IQbservable.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Linq/IQbservableProvider.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Subjects/IConnectableObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Subjects/ISubject.cs +../../../external/rx/Rx.NET/System.Reactive.Interfaces/Reactive/Subjects/ISubject.Multi.cs diff --git a/mcs/class/System.Reactive.Interfaces/more_build_args b/mcs/class/System.Reactive.Interfaces/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/System.Reactive.Interfaces/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/System.Reactive.Linq/Makefile b/mcs/class/System.Reactive.Linq/Makefile new file mode 100644 index 00000000000..853d222a4fb --- /dev/null +++ b/mcs/class/System.Reactive.Linq/Makefile @@ -0,0 +1,59 @@ +thisdir = class/System.Reactive.Linq +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Linq.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll + +ifeq (true, $(GENERATE_RESOURCES)) +LIB_MCS_FLAGS += /define:GENERATING_RESOURCES +endif + +RESX_RESOURCES = \ + Strings_Linq.resources + +CLEAN_FILES += $(RESX_RESOURCES) + +RESOURCES = $(RESX_RESOURCES) + +PREBUILT = $(RESX_RESOURCES:=.prebuilt) + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Linq.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make + +$(the_lib): $(RESOURCES) + +$(RESX_RESOURCES): %.resources: %.resx + $(RESGEN) $< || cp $@.prebuilt $@ + +$(PREBUILT): %.prebuilt: % + cp $* $@ + +dist-default: $(PREBUILT) + diff --git a/mcs/class/System.Reactive.Linq/Strings_Linq.resources.prebuilt b/mcs/class/System.Reactive.Linq/Strings_Linq.resources.prebuilt new file mode 100644 index 00000000000..f46874b1946 Binary files /dev/null and b/mcs/class/System.Reactive.Linq/Strings_Linq.resources.prebuilt differ diff --git a/mcs/class/System.Reactive.Linq/Strings_Linq.resx b/mcs/class/System.Reactive.Linq/Strings_Linq.resx new file mode 100644 index 00000000000..8965ebb7e18 --- /dev/null +++ b/mcs/class/System.Reactive.Linq/Strings_Linq.resx @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + {0} cannot be called when the scheduler is already running. Try using Sleep instead. + + + Could not find event '{0}' on object of type '{1}'. + + + Could not find event '{0}' on type '{1}'. + + + Add method should take 1 parameter. + + + The second parameter of the event delegate must be assignable to '{0}'. + + + Event is missing the add method. + + + Event is missing the remove method. + + + The event delegate must have a void return type. + + + The event delegate must have exactly two parameters. + + + Remove method should take 1 parameter. + + + The first parameter of the event delegate must be assignable to '{0}'. + + + Remove method of a WinRT event should take an EventRegistrationToken. + Only onn platforms supporting WinRT. + + + Sequence contains more than one element. + + + Sequence contains more than one matching element. + + + Sequence contains no elements. + + + Sequence contains no matching element. + + \ No newline at end of file diff --git a/mcs/class/System.Reactive.Linq/System.Reactive.Linq.dll.sources b/mcs/class/System.Reactive.Linq/System.Reactive.Linq.dll.sources new file mode 100644 index 00000000000..896357503b0 --- /dev/null +++ b/mcs/class/System.Reactive.Linq/System.Reactive.Linq.dll.sources @@ -0,0 +1,171 @@ +../../../external/rx/Rx.NET/System.Reactive.Linq/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/NamespaceDocs.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Concurrency/VirtualTimeScheduler.Extensions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/ConcatSink.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/Constants.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/Helpers.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/IConcatenatable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/IEvaluatableObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/QueryServices.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/ReflectionUtils.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/HashSet.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/Lookup.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/LocalQueryMethodImplementationTypeAttribute.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Case.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Collect.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/If.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/For.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DoWhile.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/While.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLastBuffer.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Next.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MostRecent.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Latest.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/PushToPullAdapter.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/RefCount.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Multicast.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupBy.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable_.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage_.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Joins.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Multiple.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Single.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.StandardSequenceOperators.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Time.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Awaiter.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Binding.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Blocking.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Concurrency.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Conversions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Events.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Aggregates.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Imperative.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/IQueryLanguage.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Imperative.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/EventPatternSourceBase.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/EventPattern.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/EventPatternSource.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/EventSource.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/InternalsVisibleTo.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Async.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Events.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Concurrency/HistoricalScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Concurrency/VirtualTimeScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/AnonymousEnumerable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/BinaryObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AddRef.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Aggregate.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/All.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Amb.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Any.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/AsObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Average.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Buffer.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Catch.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Concat.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Contains.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Cast.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/CombineLatest.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GetEnumerator.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupJoin.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Join.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SelectMany.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Zip.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OfType.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Count.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DefaultIfEmpty.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Defer.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Delay.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DelaySubscription.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Dematerialize.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Distinct.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/DistinctUntilChanged.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Do.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ElementAt.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Empty.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Finally.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FirstAsync.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ForEach.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEvent.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/FromEventPattern.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Generate.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/GroupByUntil.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IgnoreElements.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/IsEmpty.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LastAsync.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/LongCount.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Materialize.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Max.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MaxBy.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Merge.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Min.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/MinBy.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Never.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/OnErrorResumeNext.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Range.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Repeat.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Return.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sample.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Scan.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Select.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SequenceEqual.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SingleAsync.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Skip.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipLast.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipUntil.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/SkipWhile.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Sum.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Switch.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/TailRecursiveSink.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Take.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeLast.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeUntil.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TakeWhile.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throttle.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Throw.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/TimeInterval.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timeout.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timer.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Timestamp.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToArray.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToDictionary.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToList.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToLookup.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/ToObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Using.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Where.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/Window.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observαble/_.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/ConnectableObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/Subject.Extensions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/Either.Generic.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/AsyncSubject.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/BehaviorSubject.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/Subject.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/GroupedObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Joins/ActivePlan.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Joins/JoinObserver.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Joins/Pattern.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Joins/Plan.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Aggregates.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Awaiter.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Binding.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Blocking.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Concurrency.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Conversions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Creation.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Joins.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Multiple.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Single.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.StandardSequenceOperators.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Linq/Observable.Time.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Internal/PushPullAdapter.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Subjects/ReplaySubject.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Threading/Tasks/NamespaceDoc.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Threading/Tasks/TaskObservableExtensions.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/TimeInterval.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Reactive/Timestamped.cs +../../../external/rx/Rx.NET/System.Reactive.Linq/Strings_Linq.Generated.cs diff --git a/mcs/class/System.Reactive.Linq/more_build_args b/mcs/class/System.Reactive.Linq/more_build_args new file mode 100644 index 00000000000..d2c11c880ab --- /dev/null +++ b/mcs/class/System.Reactive.Linq/more_build_args @@ -0,0 +1,4 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub +-resource:Strings_Linq.resources,System.Reactive.Strings_Linq.resources diff --git a/mcs/class/System.Reactive.PlatformServices/Makefile b/mcs/class/System.Reactive.PlatformServices/Makefile new file mode 100644 index 00000000000..05f493f33c7 --- /dev/null +++ b/mcs/class/System.Reactive.PlatformServices/Makefile @@ -0,0 +1,65 @@ +thisdir = class/System.Reactive.PlatformServices +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.PlatformServices.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll + +ifeq (true, $(GENERATE_RESOURCES)) +LIB_MCS_FLAGS += /define:GENERATING_RESOURCES +endif + +RESX_RESOURCES = \ + Strings_PlatformServices.resources + +CLEAN_FILES += $(RESX_RESOURCES) + +RESOURCES = $(RESX_RESOURCES) + +PREBUILT = $(RESX_RESOURCES:=.prebuilt) + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +NO_TASK_DELAY := $(filter 4.5 2.1, $(FRAMEWORK_VERSION)) +ifndef NO_TASK_DELAY +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -r:Mono.Reactive.Tests.dll + +EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.PlatformServices.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make + +$(the_lib): $(RESOURCES) + +$(RESX_RESOURCES): %.resources: %.resx + $(RESGEN) $< || cp $@.prebuilt $@ + +$(PREBUILT): %.prebuilt: % + cp $* $@ + +dist-default: $(PREBUILT) + diff --git a/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resources.prebuilt b/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resources.prebuilt new file mode 100644 index 00000000000..1612fc589c2 Binary files /dev/null and b/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resources.prebuilt differ diff --git a/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resx b/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resx new file mode 100644 index 00000000000..f796d0aee72 --- /dev/null +++ b/mcs/class/System.Reactive.PlatformServices/Strings_PlatformServices.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The WinRT thread pool doesn't support creating periodic timers with a period below 1 millisecond. + + \ No newline at end of file diff --git a/mcs/class/System.Reactive.PlatformServices/System.Reactive.PlatformServices.dll.sources b/mcs/class/System.Reactive.PlatformServices/System.Reactive.PlatformServices.dll.sources new file mode 100644 index 00000000000..9950bee597d --- /dev/null +++ b/mcs/class/System.Reactive.PlatformServices/System.Reactive.PlatformServices.dll.sources @@ -0,0 +1,18 @@ +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.Windows.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/EventLoopScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/NewThreadScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/Thread.Stub.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/ThreadPoolScheduler.Windows.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/EnlightenmentProvider.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/HostLifecycleNotifications.WindowsPhone.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/HostLifecycleNotifications.Windows.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/PhoneShellThunks.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/StopwatchImpl.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/TaskPoolScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Concurrency/ThreadPoolScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/ExceptionServicesImpl.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Reactive/Internal/PlatformEnlightenmentProvider.cs +../../../external/rx/Rx.NET/System.Reactive.PlatformServices/Strings_PlatformServices.Generated.cs diff --git a/mcs/class/System.Reactive.PlatformServices/more_build_args b/mcs/class/System.Reactive.PlatformServices/more_build_args new file mode 100644 index 00000000000..630b370624e --- /dev/null +++ b/mcs/class/System.Reactive.PlatformServices/more_build_args @@ -0,0 +1,4 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub +-resource:Strings_PlatformServices.resources,System.Reactive.Strings_PlatformServices.resources diff --git a/mcs/class/System.Reactive.Providers/Makefile b/mcs/class/System.Reactive.Providers/Makefile new file mode 100644 index 00000000000..7ce54a26b51 --- /dev/null +++ b/mcs/class/System.Reactive.Providers/Makefile @@ -0,0 +1,60 @@ +thisdir = class/System.Reactive.Providers +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Providers.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll + +ifeq (true, $(GENERATE_RESOURCES)) +LIB_MCS_FLAGS += /define:GENERATING_RESOURCES +endif + +RESX_RESOURCES = \ + Strings_Providers.resources + +CLEAN_FILES += $(RESX_RESOURCES) + +RESOURCES = $(RESX_RESOURCES) + +PREBUILT = $(RESX_RESOURCES:=.prebuilt) + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Providers.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make + +$(the_lib): $(RESOURCES) + +$(RESX_RESOURCES): %.resources: %.resx + $(RESGEN) $< || cp $@.prebuilt $@ + +$(PREBUILT): %.prebuilt: % + cp $* $@ + +dist-default: $(PREBUILT) + diff --git a/mcs/class/System.Reactive.Providers/Strings_Providers.resources.prebuilt b/mcs/class/System.Reactive.Providers/Strings_Providers.resources.prebuilt new file mode 100644 index 00000000000..de6ece629f9 Binary files /dev/null and b/mcs/class/System.Reactive.Providers/Strings_Providers.resources.prebuilt differ diff --git a/mcs/class/System.Reactive.Providers/Strings_Providers.resx b/mcs/class/System.Reactive.Providers/Strings_Providers.resx new file mode 100644 index 00000000000..aba90dde0cd --- /dev/null +++ b/mcs/class/System.Reactive.Providers/Strings_Providers.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Expected Qbservable.ToQueryable. + + + Invalid expression tree type. + + + There is no method '{0}' on type '{1}' that matches the specified arguments. + + \ No newline at end of file diff --git a/mcs/class/System.Reactive.Providers/System.Reactive.Providers.dll.sources b/mcs/class/System.Reactive.Providers/System.Reactive.Providers.dll.sources new file mode 100644 index 00000000000..13780f9bd37 --- /dev/null +++ b/mcs/class/System.Reactive.Providers/System.Reactive.Providers.dll.sources @@ -0,0 +1,12 @@ +../../../external/rx/Rx.NET/System.Reactive.Providers/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Internal/Constants.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Joins/QueryablePattern.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Joins/QueryablePlan.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Linq/ExpressionVisitor.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Linq/Observable.Queryable.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Linq/Qbservable.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Linq/Qbservable.Generated.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/Linq/Qbservable.Joins.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Reactive/ObservableQuery.cs +../../../external/rx/Rx.NET/System.Reactive.Providers/Strings_Providers.Generated.cs diff --git a/mcs/class/System.Reactive.Providers/more_build_args b/mcs/class/System.Reactive.Providers/more_build_args new file mode 100644 index 00000000000..264c0c0aca6 --- /dev/null +++ b/mcs/class/System.Reactive.Providers/more_build_args @@ -0,0 +1,4 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub +-resource:Strings_Providers.resources,System.Reactive.Strings_Providers.resources diff --git a/mcs/class/System.Reactive.Runtime.Remoting/Makefile b/mcs/class/System.Reactive.Runtime.Remoting/Makefile new file mode 100644 index 00000000000..948dcef4f1b --- /dev/null +++ b/mcs/class/System.Reactive.Runtime.Remoting/Makefile @@ -0,0 +1,36 @@ +thisdir = class/System.Reactive.Runtime.Remoting +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Runtime.Remoting.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Runtime.Remoting.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/System.Reactive.Runtime.Remoting/System.Reactive.Runtime.Remoting.dll.sources b/mcs/class/System.Reactive.Runtime.Remoting/System.Reactive.Runtime.Remoting.dll.sources new file mode 100644 index 00000000000..ee06dc6b336 --- /dev/null +++ b/mcs/class/System.Reactive.Runtime.Remoting/System.Reactive.Runtime.Remoting.dll.sources @@ -0,0 +1,4 @@ +../../../external/rx/Rx.NET/System.Reactive.Runtime.Remoting/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Runtime.Remoting/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Runtime.Remoting/Reactive/Linq/Observable.Remoting.cs +../../../external/rx/Rx.NET/System.Reactive.Runtime.Remoting/Reactive/Linq/QueryLanguage.Remoting.cs diff --git a/mcs/class/System.Reactive.Runtime.Remoting/more_build_args b/mcs/class/System.Reactive.Runtime.Remoting/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/System.Reactive.Runtime.Remoting/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/System.Reactive.Windows.Forms/Makefile b/mcs/class/System.Reactive.Windows.Forms/Makefile new file mode 100644 index 00000000000..7fb7d8fbf04 --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Forms/Makefile @@ -0,0 +1,37 @@ +thisdir = class/System.Reactive.Windows.Forms +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Windows.Forms.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll \ + -r:System.Windows.Forms.dll + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Windows.Forms.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/System.Reactive.Windows.Forms/System.Reactive.Windows.Forms.dll.sources b/mcs/class/System.Reactive.Windows.Forms/System.Reactive.Windows.Forms.dll.sources new file mode 100644 index 00000000000..ab1f8f9ad79 --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Forms/System.Reactive.Windows.Forms.dll.sources @@ -0,0 +1,4 @@ +../../../external/rx/Rx.NET/System.Reactive.Windows.Forms/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Forms/Reactive/Linq/ControlObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Forms/Reactive/Concurrency/ControlScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Forms/Properties/AssemblyInfo.cs diff --git a/mcs/class/System.Reactive.Windows.Forms/more_build_args b/mcs/class/System.Reactive.Windows.Forms/more_build_args new file mode 100644 index 00000000000..a53ee7b7f9c --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Forms/more_build_args @@ -0,0 +1,3 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub diff --git a/mcs/class/System.Reactive.Windows.Threading/Makefile b/mcs/class/System.Reactive.Windows.Threading/Makefile new file mode 100644 index 00000000000..ba111236f86 --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Threading/Makefile @@ -0,0 +1,61 @@ +thisdir = class/System.Reactive.Windows.Threading +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Reactive.Windows.Threading.dll +LIB_MCS_FLAGS = \ + @more_build_args \ + -r:System.dll \ + -r:System.Core.dll \ + -r:System.Reactive.Interfaces.dll \ + -r:System.Reactive.Core.dll \ + -r:System.Reactive.Linq.dll \ + -r:WindowsBase.dll + +ifeq (true, $(GENERATE_RESOURCES)) +LIB_MCS_FLAGS += /define:GENERATING_RESOURCES +endif + +RESX_RESOURCES = \ + Strings_WindowsThreading.resources + +CLEAN_FILES += $(RESX_RESOURCES) + +RESOURCES = $(RESX_RESOURCES) + +PREBUILT = $(RESX_RESOURCES:=.prebuilt) + +ifeq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NO_TASK_DELAY +endif + +NET_4_5 := $(filter 4.5, $(FRAMEWORK_VERSION)) +ifdef NET_4_5 +LIB_MCS_FLAGS += -d:HAS_EDI -d:PREFERASYNC -d:PREFER_ASYNC +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) + +VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.System.Reactive.Windows.Threading.dll +NO_SIGN_ASSEMBLY = yes +endif + +NO_INSTALL = yes +NO_TEST = yes + +include ../../build/library.make + +$(the_lib): $(RESOURCES) + +$(RESX_RESOURCES): %.resources: %.resx + $(RESGEN) $< || cp $@.prebuilt $@ + +$(PREBUILT): %.prebuilt: % + cp $* $@ + +dist-default: $(PREBUILT) + diff --git a/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resources.prebuilt b/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resources.prebuilt new file mode 100644 index 00000000000..6173d36a34a Binary files /dev/null and b/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resources.prebuilt differ diff --git a/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resx b/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resx new file mode 100644 index 00000000000..85f51011e5c --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Threading/Strings_WindowsThreading.resx @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The current thread has no Dispatcher associated with it. + Only on WPF/SL. + + + No current Window object found to obtain a CoreDispatcher from. + Only on Jupiter. + + \ No newline at end of file diff --git a/mcs/class/System.Reactive.Windows.Threading/System.Reactive.Windows.Threading.dll.sources b/mcs/class/System.Reactive.Windows.Threading/System.Reactive.Windows.Threading.dll.sources new file mode 100644 index 00000000000..7b287a88233 --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Threading/System.Reactive.Windows.Threading.dll.sources @@ -0,0 +1,8 @@ +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/GlobalSuppressions.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Reactive/Concurrency/CoreDispatcherScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Reactive/Internal/Constants.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Reactive/Linq/CoreDispatcherObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Reactive/Linq/DispatcherObservable.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Reactive/Concurrency/DispatcherScheduler.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Properties/AssemblyInfo.cs +../../../external/rx/Rx.NET/System.Reactive.Windows.Threading/Strings_WindowsThreading.Generated.cs diff --git a/mcs/class/System.Reactive.Windows.Threading/more_build_args b/mcs/class/System.Reactive.Windows.Threading/more_build_args new file mode 100644 index 00000000000..aa3becfe111 --- /dev/null +++ b/mcs/class/System.Reactive.Windows.Threading/more_build_args @@ -0,0 +1,4 @@ +-d:SIGNED +-delaysign +-keyfile:../reactive.pub +-resource:Strings_WindowsThreading.resources,System.Reactive.Strings_WindowsThreading.resources diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/TypeMap.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/TypeMap.cs index aa6aba42b6b..6d18817c20f 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/TypeMap.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/TypeMap.cs @@ -174,14 +174,23 @@ namespace System.Runtime.Serialization.Json OnDeserializing = mi; else if (mi.GetCustomAttributes (typeof (OnDeserializedAttribute), false).Length > 0) OnDeserialized = mi; + else if (mi.GetCustomAttributes (typeof (OnSerializingAttribute), false).Length > 0) + OnSerializing = mi; + else if (mi.GetCustomAttributes (typeof (OnSerializedAttribute), false).Length > 0) + OnSerialized = mi; } } public MethodInfo OnDeserializing { get; set; } public MethodInfo OnDeserialized { get; set; } + public MethodInfo OnSerializing { get; set; } + public MethodInfo OnSerialized { get; set; } public virtual void Serialize (JsonSerializationWriter outputter, object graph, string type) { + if (OnSerializing != null) + OnSerializing.Invoke (graph, new object [] {new StreamingContext (StreamingContextStates.All)}); + outputter.Writer.WriteAttributeString ("type", type); foreach (TypeMapMember member in members) { object memberObj = member.GetMemberOf (graph); @@ -190,6 +199,9 @@ namespace System.Runtime.Serialization.Json outputter.WriteObjectContent (memberObj, false, false); outputter.Writer.WriteEndElement (); } + + if (OnSerialized != null) + OnSerialized.Invoke (graph, new object [] {new StreamingContext (StreamingContextStates.All)}); } internal static object CreateInstance (Type type) diff --git a/mcs/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs b/mcs/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs index f27a2d9d27b..a41802469eb 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs +++ b/mcs/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs @@ -411,6 +411,16 @@ namespace MonoTests.System Assert.AreEqual ("vv", m.QueryParameters ["p1"], "#5"); } + [Test] + public void Match3 () + { + var template = new UriTemplate ("test"); + var match1 = template.Match (new Uri ("http://something"), new Uri ("http://something/test")); + var match2 = template.Match (new Uri ("http://something/something2"), new Uri ("http://something/something2/test")); + Assert.IsNotNull (match1, "#1"); + Assert.IsNotNull (match2, "#2"); + } + [Test] public void MatchWildcard () { diff --git a/mcs/class/System.ServiceModel/Makefile b/mcs/class/System.ServiceModel/Makefile index 85f8666ad66..1aaf90fae44 100755 --- a/mcs/class/System.ServiceModel/Makefile +++ b/mcs/class/System.ServiceModel/Makefile @@ -48,7 +48,8 @@ TEST_EXTRA_FILES = \ Test/XmlFiles/* \ Test/System.ServiceModel.Channels/soap-fault*.xml \ Test/System.ServiceModel.Channels/binary-message.raw \ - Test/System.ServiceModel.Description/dump.xml + Test/System.ServiceModel.Description/dump.xml \ + Test/MetadataTests/Resources/* EXTRA_DISTFILES = $(RESOURCE_FILES) $(TEST_EXTRA_FILES) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel-net_4_5.csproj b/mcs/class/System.ServiceModel/System.ServiceModel-net_4_5.csproj index 35e67b9c082..66f2673acf8 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel-net_4_5.csproj +++ b/mcs/class/System.ServiceModel/System.ServiceModel-net_4_5.csproj @@ -182,7 +182,8 @@ - + + diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageEncodingBindingElementImporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageEncodingBindingElementImporter.cs index fe96d70eec9..27bfc263bae 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageEncodingBindingElementImporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageEncodingBindingElementImporter.cs @@ -1,9 +1,10 @@ // // MessageEncodingBindingElementImporter.cs // -// Author: Atsushi Enomoto (atsushi@ximian.com) +// Author: +// Martin Baulig // -// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// Copyright (c) 2012 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 @@ -39,7 +40,6 @@ namespace System.ServiceModel.Channels public class MessageEncodingBindingElementImporter : IWsdlImportExtension, IPolicyImportExtension { - [MonoTODO] void IWsdlImportExtension.BeforeImport ( ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, @@ -47,22 +47,35 @@ namespace System.ServiceModel.Channels { } - [MonoTODO] void IWsdlImportExtension.ImportContract (WsdlImporter importer, WsdlContractConversionContext context) { } - [MonoTODO] void IWsdlImportExtension.ImportEndpoint (WsdlImporter importer, WsdlEndpointConversionContext context) { } - [MonoTODO] void IPolicyImportExtension.ImportPolicy (MetadataImporter importer, PolicyConversionContext context) { + var assertions = context.GetBindingAssertions (); + + var mtom = PolicyImportHelper.GetMtomMessageEncodingPolicy (assertions); + if (mtom != null) { + // http://www.w3.org/Submission/WS-MTOMPolicy/ + context.BindingElements.Add (new MtomMessageEncodingBindingElement ()); + return; + } + + var binary = PolicyImportHelper.GetBinaryMessageEncodingPolicy (assertions); + if (binary != null) { + context.BindingElements.Add (new BinaryMessageEncodingBindingElement ()); + return; + } + + context.BindingElements.Add (new TextMessageEncodingBindingElement ()); } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PolicyImportHelper.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PolicyImportHelper.cs new file mode 100644 index 00000000000..517d5fe2cf8 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PolicyImportHelper.cs @@ -0,0 +1,224 @@ +// +// PolicyImportHelper.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Xml; +using System.Collections.Generic; +using System.ServiceModel.Description; + +using QName = System.Xml.XmlQualifiedName; + +namespace System.ServiceModel.Channels { + + internal static class PolicyImportHelper { + + internal const string SecurityPolicyNS = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"; + internal const string PolicyNS = "http://schemas.xmlsoap.org/ws/2004/09/policy"; + internal const string MimeSerializationNS = "http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization"; + internal const string HttpAuthNS = "http://schemas.microsoft.com/ws/06/2004/policy/http"; + + internal const string FramingPolicyNS = "http://schemas.microsoft.com/ws/2006/05/framing/policy"; + internal const string NetBinaryEncodingNS = "http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1"; + + internal static XmlElement GetTransportBindingPolicy (PolicyAssertionCollection collection) + { + return FindAndRemove (collection, "TransportBinding", SecurityPolicyNS); + } + + internal static XmlElement GetStreamedMessageFramingPolicy (PolicyAssertionCollection collection) + { + return FindAndRemove (collection, "Streamed", FramingPolicyNS); + } + + internal static XmlElement GetBinaryMessageEncodingPolicy (PolicyAssertionCollection collection) + { + return FindAndRemove (collection, "BinaryEncoding", NetBinaryEncodingNS); + } + + internal static XmlElement GetMtomMessageEncodingPolicy (PolicyAssertionCollection collection) + { + return FindAndRemove (collection, "OptimizedMimeSerialization", MimeSerializationNS); + } + + static XmlElement FindAndRemove (PolicyAssertionCollection collection, string name, string ns) + { + var element = collection.Find (name, ns); + if (element != null) + collection.Remove (element); + return element; + } + + internal static List FindAssertionByNS ( + PolicyAssertionCollection collection, string ns) + { + var list = new List (); + foreach (var assertion in collection) { + if (assertion.NamespaceURI.Equals (ns)) + list.Add (assertion); + } + return list; + } + + internal static List GetPolicyElements (XmlElement root, out bool error) + { + XmlElement policy = null; + var list = new List (); + + foreach (var node in root.ChildNodes) { + var e = node as XmlElement; + if (e == null) + continue; + if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) { + error = true; + return list; + } + if (policy != null) { + error = true; + return list; + } + policy = e; + } + + if (policy == null) { + error = true; + return list; + } + + foreach (var node in policy.ChildNodes) { + var e = node as XmlElement; + if (e != null) + list.Add (e); + } + + error = false; + return list; + } + + internal static bool FindPolicyElement (MetadataImporter importer, XmlElement root, + QName name, bool required, bool removeWhenFound, + out XmlElement element) + { + if (!FindPolicyElement (root, name, removeWhenFound, out element)) { + importer.AddWarning ("Invalid policy element: {0}", root.OuterXml); + return false; + } + if (required && (element == null)) { + importer.AddWarning ("Did not find policy element `{0}'.", name); + return false; + } + return true; + } + + internal static bool FindPolicyElement (XmlElement root, QName name, + bool removeWhenFound, out XmlElement element) + { + XmlElement policy = null; + foreach (var node in root.ChildNodes) { + var e = node as XmlElement; + if (e == null) + continue; + if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) { + element = null; + return false; + } + if (policy != null) { + element = null; + return false; + } + policy = e; + } + + if (policy == null) { + element = null; + return true; + } + + element = null; + foreach (var node in policy.ChildNodes) { + var e = node as XmlElement; + if (e == null) + continue; + if (!name.Namespace.Equals (e.NamespaceURI) || !name.Name.Equals (e.LocalName)) + continue; + + element = e; + break; + } + + if (!removeWhenFound || (element == null)) + return true; + + policy.RemoveChild (element); + + bool foundAnother = false; + foreach (var node in policy.ChildNodes) { + var e = node as XmlElement; + if (e != null) { + foundAnother = true; + break; + } + } + + if (!foundAnother) + root.RemoveChild (policy); + return true; + } + + internal static XmlElement GetElement (MetadataImporter importer, + XmlElement root, string name, string ns) + { + return GetElement (importer, root, name, ns, false); + } + + internal static XmlElement GetElement (MetadataImporter importer, + XmlElement root, string name, string ns, + bool required) + { + return GetElement (importer, root, new QName (name, ns), required); + } + + internal static XmlElement GetElement (MetadataImporter importer, + XmlElement root, QName name, bool required) + { + var list = root.GetElementsByTagName (name.Name, name.Namespace); + if (list.Count < 1) { + if (required) + importer.AddWarning ("Did not find required policy element `{0}'", name); + return null; + } + + if (list.Count > 1) { + importer.AddWarning ("Found duplicate policy element `{0}'", name); + return null; + } + + var element = list [0] as XmlElement; + if (required && (element == null)) + importer.AddWarning ("Did not find required policy element `{0}'", name); + return element; + } + } +} + diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/StandardBindingImporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/StandardBindingImporter.cs index 2147439eea9..a555cf8781d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/StandardBindingImporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/StandardBindingImporter.cs @@ -2,59 +2,322 @@ // StandardBindingImporter.cs // // Author: -// Atsushi Enomoto +// Martin Baulig // -// Copyright (C) 2005 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + using System; -using System.Collections.Generic; -using System.ServiceModel.Description; -using System.Web.Services.Description; +using System.Net; using System.Xml; using System.Xml.Schema; +using System.Collections.Generic; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; + +using WS = System.Web.Services.Description; +using QName = System.Xml.XmlQualifiedName; + +namespace System.ServiceModel.Channels { + + public class StandardBindingImporter : IWsdlImportExtension { + #region IWsdlImportExtension implementation + + public void BeforeImport (WS.ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, + ICollection policy) + { + } + + public void ImportContract (WsdlImporter importer, WsdlContractConversionContext contractContext) + { + } + + WS.Port LookupPort (WsdlImporter importer, QName name) + { + foreach (WS.ServiceDescription doc in importer.WsdlDocuments) { + foreach (WS.Service service in doc.Services) { + foreach (WS.Port port in service.Ports) { + if (!name.Namespace.Equals (port.Binding.Namespace)) + continue; + if (!name.Name.Equals (port.Binding.Name)) + continue; + return port; + } + } + } + + return null; + } + + public void ImportEndpoint (WsdlImporter importer, WsdlEndpointConversionContext context) + { + var custom = context.Endpoint.Binding as CustomBinding; + if (custom == null) + return; + + var soapHttp = GetHttpSoapBinding (context.WsdlBinding); + if (soapHttp != null) { + ImportBasicHttpBinding (importer, context, custom, soapHttp); + return; + } + + var soapTcp = GetTcpSoapBinding (context.WsdlBinding); + if (soapTcp != null) { + ImportNetTcpBinding (importer, context, custom, soapTcp); + return; + } + } -namespace System.ServiceModel.Channels -{ - [MonoTODO] - public class StandardBindingImporter : IWsdlImportExtension - { - [MonoTODO] - void IWsdlImportExtension.BeforeImport ( - ServiceDescriptionCollection wsdlDocuments, - XmlSchemaSet xmlSchemas, - ICollection policy) + internal static WS.SoapBinding GetHttpSoapBinding (WS.Binding binding) { + WS.SoapBinding soap = null; + foreach (var extension in binding.Extensions) { + var check = extension as WS.SoapBinding; + if (check != null) { + soap = check; + break; + } + } + + if (soap == null) + return null; + if (soap.Transport != WS.SoapBinding.HttpTransport) + return null; + if (soap.Style != WS.SoapBindingStyle.Document) + return null; + return soap; } - [MonoTODO] - void IWsdlImportExtension.ImportContract (WsdlImporter importer, - WsdlContractConversionContext context) + const string TcpTransport = "http://schemas.microsoft.com/soap/tcp"; + + internal static WS.Soap12Binding GetTcpSoapBinding (WS.Binding binding) { + WS.Soap12Binding soap = null; + foreach (var extension in binding.Extensions) { + var check = extension as WS.Soap12Binding; + if (check != null) { + soap = check; + break; + } + } + + if (soap == null) + return null; + if (soap.Transport != TcpTransport) + return null; + if (soap.Style != WS.SoapBindingStyle.Document) + return null; + return soap; } - [MonoTODO] - void IWsdlImportExtension.ImportEndpoint (WsdlImporter importer, - WsdlEndpointConversionContext context) + bool ImportBasicHttpBinding ( + WsdlImporter importer, WsdlEndpointConversionContext context, + CustomBinding custom, WS.SoapBinding soap) { + TransportBindingElement transportElement = null; + MtomMessageEncodingBindingElement mtomElement = null; + TextMessageEncodingBindingElement textElement = null; + bool foundUnknownElement = false; + + foreach (var element in custom.Elements) { + if (element is TransportBindingElement) + transportElement = (TransportBindingElement)element; + else if (element is MtomMessageEncodingBindingElement) + mtomElement = (MtomMessageEncodingBindingElement)element; + else if (element is TextMessageEncodingBindingElement) + textElement = (TextMessageEncodingBindingElement)element; + else { + importer.AddWarning ( + "Found unknown binding element `{0}' while attempting " + + "to import binding `{0}'.", element.GetType (), + custom.Name); + foundUnknownElement = true; + } + } + + if (foundUnknownElement) + return false; + + if ((mtomElement != null) && (textElement != null)) { + // FIXME: Should never happen + importer.AddWarning ( + "Found both MtomMessageEncodingBindingElement and " + + "TextMessageEncodingBindingElement while attempting to " + + "import binding `{0}'.", custom.Name); + return false; + } + + BasicHttpBinding httpBinding; + AuthenticationSchemes authScheme; + + /* + * FIXME: Maybe make the BasicHttpBinding use the transport element + * that we created with the TransportBindingElementImporter ? + * + * There seems to be no public API to do that, so maybe add a private .ctor ? + * + */ + + var httpsTransport = transportElement as HttpsTransportBindingElement; + var httpTransport = transportElement as HttpTransportBindingElement; + + if (httpsTransport != null) { + httpBinding = new BasicHttpBinding (BasicHttpSecurityMode.Transport); + authScheme = httpsTransport.AuthenticationScheme; + } else if (httpTransport != null) { + authScheme = httpTransport.AuthenticationScheme; + if ((authScheme != AuthenticationSchemes.None) && + (authScheme != AuthenticationSchemes.Anonymous)) + httpBinding = new BasicHttpBinding ( + BasicHttpSecurityMode.TransportCredentialOnly); + else + httpBinding = new BasicHttpBinding (); + } else { + httpBinding = new BasicHttpBinding (); + authScheme = AuthenticationSchemes.Anonymous; + } + + if (mtomElement != null) + httpBinding.MessageEncoding = WSMessageEncoding.Mtom; + else if (textElement != null) + httpBinding.MessageEncoding = WSMessageEncoding.Text; + else { + importer.AddWarning ( + "Found neither MtomMessageEncodingBindingElement nor " + + "TextMessageEncodingBindingElement while attempting to " + + "import binding `{0}'.", custom.Name); + return false; + } + + httpBinding.Name = context.Endpoint.Binding.Name; + httpBinding.Namespace = context.Endpoint.Binding.Namespace; + + switch (authScheme) { + case AuthenticationSchemes.None: + case AuthenticationSchemes.Anonymous: + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; + break; + case AuthenticationSchemes.Basic: + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; + break; + case AuthenticationSchemes.Digest: + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest; + break; + case AuthenticationSchemes.Ntlm: + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; + break; + case AuthenticationSchemes.Negotiate: + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; + break; + default: + importer.AddWarning ("Invalid auth scheme: {0}", authScheme); + return false; + } + + if ((httpsTransport != null) && httpsTransport.RequireClientCertificate) { + if (httpBinding.Security.Transport.ClientCredentialType != HttpClientCredentialType.None) { + importer.AddWarning ("Cannot use both client certificate and explicit auth type."); + return false; + } + httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; + } + + context.Endpoint.Binding = httpBinding; + return true; } + + bool ImportNetTcpBinding ( + WsdlImporter importer, WsdlEndpointConversionContext context, + CustomBinding custom, WS.Soap12Binding soap) + { + TcpTransportBindingElement transportElement = null; + BinaryMessageEncodingBindingElement binaryElement = null; + TransactionFlowBindingElement transactionFlowElement = null; + WindowsStreamSecurityBindingElement windowsStreamElement = null; + SslStreamSecurityBindingElement sslStreamElement = null; + bool foundUnknownElement = false; + + foreach (var element in custom.Elements) { + if (element is TcpTransportBindingElement) + transportElement = (TcpTransportBindingElement)element; + else if (element is BinaryMessageEncodingBindingElement) + binaryElement = (BinaryMessageEncodingBindingElement)element; + else if (element is TransactionFlowBindingElement) + transactionFlowElement = (TransactionFlowBindingElement)element; + else if (element is WindowsStreamSecurityBindingElement) + windowsStreamElement = (WindowsStreamSecurityBindingElement)element; + else if (element is SslStreamSecurityBindingElement) + sslStreamElement = (SslStreamSecurityBindingElement)element; + else { + importer.AddWarning ( + "Found unknown binding element `{0}' while importing " + + "binding `{1}'.", element.GetType (), custom.Name); + foundUnknownElement = true; + } + } + + if (foundUnknownElement) + return false; + + if (transportElement == null) { + importer.AddWarning ( + "Missing TcpTransportBindingElement while importing " + + "binding `{0}'.", custom.Name); + return false; + } + if (binaryElement == null) { + importer.AddWarning ( + "Missing BinaryMessageEncodingBindingElement while importing " + + "binding `{0}'.", custom.Name); + return false; + } + + if ((windowsStreamElement != null) && (sslStreamElement != null)) { + importer.AddWarning ( + "Found both WindowsStreamSecurityBindingElement and " + + "SslStreamSecurityBindingElement while importing binding `{0}.", + custom.Name); + return false; + } + + NetTcpSecurity security; + if (windowsStreamElement != null) { + security = new NetTcpSecurity (SecurityMode.Transport); + security.Transport.ProtectionLevel = windowsStreamElement.ProtectionLevel; + } else if (sslStreamElement != null) { + security = new NetTcpSecurity (SecurityMode.TransportWithMessageCredential); + } else { + security = new NetTcpSecurity (SecurityMode.None); + } + + var netTcp = new NetTcpBinding (transportElement, security, false); + + netTcp.Name = context.Endpoint.Binding.Name; + netTcp.Namespace = context.Endpoint.Binding.Namespace; + + context.Endpoint.Binding = netTcp; + return true; + } + + #endregion } } + diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElementImporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElementImporter.cs index f323ccaba40..b76f0e12edd 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElementImporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportBindingElementImporter.cs @@ -2,94 +2,383 @@ // TransportBindingElementImporter.cs // // Author: -// Atsushi Enomoto +// Martin Baulig // -// Copyright (C) 2005 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + using System; +using System.Net; +using System.Net.Security; +using System.Xml; +using System.Xml.Schema; using System.Collections.Generic; -using System.Runtime.Serialization; using System.ServiceModel; -using System.ServiceModel.Configuration; +using System.ServiceModel.Channels; using System.ServiceModel.Description; -using System.Web.Services.Description; -using System.Xml; -using System.Xml.Schema; -namespace System.ServiceModel.Channels -{ - [MonoTODO] - public class TransportBindingElementImporter - : IWsdlImportExtension, IPolicyImportExtension - { - public TransportBindingElementImporter () +using WS = System.Web.Services.Description; +using QName = System.Xml.XmlQualifiedName; + +namespace System.ServiceModel.Channels { + + public class TransportBindingElementImporter : IWsdlImportExtension, IPolicyImportExtension { + #region IWsdlImportExtension implementation + + public void BeforeImport (WS.ServiceDescriptionCollection wsdlDocuments, XmlSchemaSet xmlSchemas, + ICollection policy) + { + } + + public void ImportContract (WsdlImporter importer, WsdlContractConversionContext contractContext) + { + } + + public void ImportEndpoint (WsdlImporter importer, WsdlEndpointConversionContext context) { + // Only import the binding, not the endpoint. + if (context.WsdlPort == null) + return; + + DoImportEndpoint (context); } - void IWsdlImportExtension.BeforeImport (ServiceDescriptionCollection wsdlDocuments, - XmlSchemaSet xmlSchemas, ICollection policy) + bool DoImportEndpoint (WsdlEndpointConversionContext context) { + if (ImportBasicHttpEndpoint (context)) + return true; + if (ImportNetTcpEndpoint (context)) + return true; + return false; } - void IWsdlImportExtension.ImportContract (WsdlImporter importer, - WsdlContractConversionContext context) + bool ImportBasicHttpEndpoint (WsdlEndpointConversionContext context) { + var http = context.Endpoint.Binding as BasicHttpBinding; + if (http == null) + return false; + + WS.SoapAddressBinding address = null; + foreach (var extension in context.WsdlPort.Extensions) { + var check = extension as WS.SoapAddressBinding; + if (check != null) { + address = check; + break; + } + } + + if (address == null) + return false; + + context.Endpoint.Address = new EndpointAddress (address.Location); + context.Endpoint.ListenUri = new Uri (address.Location); + context.Endpoint.ListenUriMode = ListenUriMode.Explicit; + return true; + } + + bool ImportNetTcpEndpoint (WsdlEndpointConversionContext context) + { + var tcp = context.Endpoint.Binding as NetTcpBinding; + if (tcp == null) + return false; + + WS.Soap12AddressBinding address = null; + foreach (var extension in context.WsdlPort.Extensions) { + var check = extension as WS.Soap12AddressBinding; + if (check != null) { + address = check; + break; + } + } + + if (address == null) + return false; + + context.Endpoint.Address = new EndpointAddress (address.Location); + context.Endpoint.ListenUri = new Uri (address.Location); + context.Endpoint.ListenUriMode = ListenUriMode.Explicit; + return true; } - void IWsdlImportExtension.ImportEndpoint(WsdlImporter importer, - WsdlEndpointConversionContext context) + #endregion + + #region IPolicyImportExtension implementation + + public void ImportPolicy (MetadataImporter importer, PolicyConversionContext context) { - for (int i = 0; i < context.WsdlBinding.Extensions.Count; i ++) { - if (context.WsdlBinding.Extensions [i] is SoapBinding) { - SoapBinding transport = context.WsdlBinding.Extensions [i] as SoapBinding; - if (transport.Transport != SoapBinding.HttpTransport) - //FIXME: not http - return; + var customCtx = context as CustomPolicyConversionContext; + var customBinding = context.Endpoint.Binding as CustomBinding; + if ((customCtx == null) || (customBinding == null)) + // FIXME: Should we allow this ? + throw new InvalidOperationException (); + + var soapHttp = StandardBindingImporter.GetHttpSoapBinding (customCtx.WsdlBinding); + if (soapHttp != null) { + if (!ImportHttpPolicy (importer, customCtx, soapHttp)) + context.BindingElements.Add (new HttpTransportBindingElement ()); + return; + } + + var soapTcp = StandardBindingImporter.GetTcpSoapBinding (customCtx.WsdlBinding); + if (soapTcp != null) { + if (!ImportTcpPolicy (importer, customCtx, soapTcp)) + context.BindingElements.Add (new TcpTransportBindingElement ()); + return; + } + } + + #endregion - if (! (context.Endpoint.Binding is CustomBinding)) - //FIXME: - throw new Exception (); + bool ImportHttpAuthScheme (MetadataImporter importer, + HttpTransportBindingElement bindingElement, + PolicyConversionContext context) + { + var assertions = context.GetBindingAssertions (); + var authSchemes = AuthenticationSchemes.None; - ((CustomBinding) context.Endpoint.Binding).Elements.Add (new HttpTransportBindingElement ()); - //((CustomBinding) context.Endpoint.Binding).Scheme = "http"; + var httpsTransport = bindingElement as HttpsTransportBindingElement; + bool certificate = httpsTransport != null ? + httpsTransport.RequireClientCertificate : false; - for (int j = 0; j < context.WsdlPort.Extensions.Count; j ++) { - SoapAddressBinding address = context.WsdlPort.Extensions [j] as SoapAddressBinding; - if (address == null) - continue; + var authElements = PolicyImportHelper.FindAssertionByNS ( + assertions, PolicyImportHelper.HttpAuthNS); + foreach (XmlElement authElement in authElements) { + assertions.Remove (authElement); - context.Endpoint.Address = new EndpointAddress (address.Location); - context.Endpoint.ListenUri = new Uri (address.Location); - } + if (certificate) { + importer.AddWarning ( + "Invalid authentication assertion while " + + "using client certificate: {0}", authElement.OuterXml); + return false; + } + switch (authElement.LocalName) { + case "BasicAuthentication": + authSchemes |= AuthenticationSchemes.Basic; + break; + case "NtlmAuthentication": + authSchemes |= AuthenticationSchemes.Ntlm; break; + case "DigestAuthentication": + authSchemes |= AuthenticationSchemes.Digest; + break; + case "NegotiateAuthentication": + authSchemes |= AuthenticationSchemes.Negotiate; + break; + default: + importer.AddWarning ( + "Invalid policy assertion: {0}", authElement.OuterXml); + return false; } } + + bindingElement.AuthenticationScheme = authSchemes; + return true; + } + + bool ImportWindowsTransportSecurity (MetadataImporter importer, + PolicyConversionContext context, + XmlElement policyElement) + { + var protectionLevel = PolicyImportHelper.GetElement ( + importer, policyElement, "ProtectionLevel", + PolicyImportHelper.FramingPolicyNS, true); + if (protectionLevel == null) { + importer.AddWarning ( + "Invalid policy assertion: {0}", policyElement.OuterXml); + return false; + } + + var element = new WindowsStreamSecurityBindingElement (); + + switch (protectionLevel.InnerText.ToLowerInvariant ()) { + case "none": + element.ProtectionLevel = ProtectionLevel.None; + break; + case "sign": + element.ProtectionLevel = ProtectionLevel.Sign; + break; + case "encryptandsign": + element.ProtectionLevel = ProtectionLevel.EncryptAndSign; + break; + default: + importer.AddWarning ( + "Invalid policy assertion: {0}", protectionLevel.OuterXml); + return false; + } + + context.BindingElements.Add (element); + return true; + } + + bool ImportTransport (MetadataImporter importer, TransportBindingElement bindingElement, + XmlElement transportPolicy) + { + XmlElement algorithmSuite, layout; + if (!PolicyImportHelper.FindPolicyElement ( + importer, transportPolicy, + new QName ("AlgorithmSuite", PolicyImportHelper.SecurityPolicyNS), + false, true, out algorithmSuite) || + !PolicyImportHelper.FindPolicyElement ( + importer, transportPolicy, + new QName ("Layout", PolicyImportHelper.SecurityPolicyNS), + false, true, out layout)) + return false; + + bool foundUnknown = false; + foreach (var node in transportPolicy.ChildNodes) { + var e = node as XmlElement; + if (e == null) + continue; + importer.AddWarning ("Unknown policy assertion: {0}", e.OuterXml); + foundUnknown = true; + } + + return !foundUnknown; + } + + bool GetTransportToken (MetadataImporter importer, XmlElement transportPolicy, + out XmlElement transportToken) + { + return PolicyImportHelper.FindPolicyElement ( + importer, transportPolicy, + new QName ("TransportToken", PolicyImportHelper.SecurityPolicyNS), + false, true, out transportToken); + } + + bool ImportHttpTransport (MetadataImporter importer, PolicyConversionContext context, + XmlElement transportPolicy, + out HttpTransportBindingElement bindingElement) + { + XmlElement transportToken; + if (!GetTransportToken (importer, transportPolicy, out transportToken)) { + bindingElement = null; + return false; + } + + if (transportToken == null) { + bindingElement = new HttpTransportBindingElement (); + return true; + } + + bool error; + var tokenElementList = PolicyImportHelper.GetPolicyElements (transportToken, out error); + if (error || (tokenElementList.Count != 1)) { + importer.AddWarning ("Invalid policy assertion: {0}", transportToken.OuterXml); + bindingElement = null; + return false; + } + + var tokenElement = tokenElementList [0]; + if (!PolicyImportHelper.SecurityPolicyNS.Equals (tokenElement.NamespaceURI) || + !tokenElement.LocalName.Equals ("HttpsToken")) { + importer.AddWarning ("Invalid policy assertion: {0}", tokenElement.OuterXml); + bindingElement = null; + return false; + } + + var httpsTransport = new HttpsTransportBindingElement (); + bindingElement = httpsTransport; + + var certAttr = tokenElement.GetAttribute ("RequireClientCertificate"); + if (!String.IsNullOrEmpty (certAttr)) + httpsTransport.RequireClientCertificate = Boolean.Parse (certAttr); + return true; + } + + bool ImportTcpTransport (MetadataImporter importer, PolicyConversionContext context, + XmlElement transportPolicy) + { + XmlElement transportToken; + if (!GetTransportToken (importer, transportPolicy, out transportToken)) + return false; + + if (transportToken == null) + return true; + + bool error; + var tokenElementList = PolicyImportHelper.GetPolicyElements (transportToken, out error); + if (error || (tokenElementList.Count != 1)) { + importer.AddWarning ("Invalid policy assertion: {0}", transportToken.OuterXml); + return false; + } + + var tokenElement = tokenElementList [0]; + if (!PolicyImportHelper.FramingPolicyNS.Equals (tokenElement.NamespaceURI)) { + importer.AddWarning ("Invalid policy assertion: {0}", tokenElement.OuterXml); + return false; + } + + if (tokenElement.LocalName.Equals ("WindowsTransportSecurity")) { + if (!ImportWindowsTransportSecurity (importer, context, tokenElement)) + return false; + } else if (tokenElement.LocalName.Equals ("SslTransportSecurity")) { + context.BindingElements.Add (new SslStreamSecurityBindingElement ()); + } + + return true; } - void IPolicyImportExtension.ImportPolicy (MetadataImporter importer, - PolicyConversionContext context) + bool ImportHttpPolicy (MetadataImporter importer, PolicyConversionContext context, + WS.SoapBinding soap) { - throw new NotImplementedException (); + HttpTransportBindingElement httpTransport; + var assertions = context.GetBindingAssertions (); + var transportPolicy = PolicyImportHelper.GetTransportBindingPolicy (assertions); + if (transportPolicy != null) { + if (!ImportHttpTransport (importer, context, transportPolicy, out httpTransport)) + return false; + if (!ImportTransport (importer, httpTransport, transportPolicy)) + return false; + } else { + httpTransport = new HttpTransportBindingElement (); + } + + if (!ImportHttpAuthScheme (importer, httpTransport, context)) + return false; + + context.BindingElements.Add (httpTransport); + return true; + } + + bool ImportTcpPolicy (MetadataImporter importer, PolicyConversionContext context, + WS.Soap12Binding soap) + { + var assertions = context.GetBindingAssertions (); + + var tcpTransport = new TcpTransportBindingElement (); + + var transportPolicy = PolicyImportHelper.GetTransportBindingPolicy (assertions); + if (transportPolicy != null) { + if (!ImportTcpTransport (importer, context, transportPolicy)) + return false; + if (!ImportTransport (importer, tcpTransport, transportPolicy)) + return false; + } + + var streamed = PolicyImportHelper.GetStreamedMessageFramingPolicy (assertions); + if (streamed != null) + tcpTransport.TransferMode = TransferMode.Streamed; + + context.BindingElements.Add (tcpTransport); + return true; } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs index fe1c268edb5..d7d86f0f7d6 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs @@ -1,6 +1,11 @@ // // BasicHttpBindingElement.cs // +// See BasicHttpBindingElement_4_5.cs and HttpBindingBaseElement.cs +// for the .NET 4.5 version of this class, where most of the code has +// been moved into the new abstract HttpBindingBaseElement class. +// +// // Author: // Atsushi Enomoto // @@ -26,6 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !NET_4_5 using System; using System.Collections; using System.Collections.Generic; @@ -250,3 +256,4 @@ namespace System.ServiceModel.Configuration } } +#endif diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement_4_5.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement_4_5.cs new file mode 100644 index 00000000000..691d90ed08f --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement_4_5.cs @@ -0,0 +1,123 @@ +// +// BasicHttpBindingElement_4_5.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public class BasicHttpBindingElement + : HttpBindingBaseElement, IBindingConfigurationElement + { + ConfigurationPropertyCollection _properties; + + public BasicHttpBindingElement () + { + } + + public BasicHttpBindingElement (string name) : base (name) { } + + protected override Type BindingElementType { + get { return typeof (BasicHttpBinding); } + } + + // Properties + + [ConfigurationProperty ("messageEncoding", + DefaultValue = "Text", + Options = ConfigurationPropertyOptions.None)] + public WSMessageEncoding MessageEncoding { + get { return (WSMessageEncoding) this ["messageEncoding"]; } + set { this ["messageEncoding"] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { + if (_properties == null) { + _properties = base.Properties; + _properties.Add (new ConfigurationProperty ("messageEncoding", typeof (WSMessageEncoding), "Text", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("security", typeof (BasicHttpSecurityElement), null, null, null, ConfigurationPropertyOptions.None)); + } + return _properties; + } + } + + [ConfigurationProperty ("security", + Options = ConfigurationPropertyOptions.None)] + public BasicHttpSecurityElement Security { + get { return (BasicHttpSecurityElement) this ["security"]; } + } + + protected override void OnApplyConfiguration (Binding binding) + { + base.OnApplyConfiguration (binding); + BasicHttpBinding basicHttpBinding = (BasicHttpBinding) binding; + + basicHttpBinding.MessageEncoding = MessageEncoding; + + basicHttpBinding.Security.Mode = Security.Mode; + Security.Transport.ApplyConfiguration (basicHttpBinding.Security.Transport); + } + + protected internal override void InitializeFrom (Binding binding) + { + BasicHttpBinding b = (BasicHttpBinding) binding; + base.InitializeFrom (binding); + + MessageEncoding = b.MessageEncoding; + + Security.Mode = b.Security.Mode; + Security.Transport.ApplyConfiguration (b.Security.Transport); + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingCollectionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingCollectionElement.cs new file mode 100644 index 00000000000..0669002f029 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingCollectionElement.cs @@ -0,0 +1,62 @@ +// +// BasicHttpsBindingCollectionElement.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public partial class BasicHttpsBindingCollectionElement + : StandardBindingCollectionElement + { + } + +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingElement.cs new file mode 100644 index 00000000000..b167b6e2372 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsBindingElement.cs @@ -0,0 +1,123 @@ +// +// BasicHttpsBindingElement.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public class BasicHttpsBindingElement + : HttpBindingBaseElement, IBindingConfigurationElement + { + ConfigurationPropertyCollection _properties; + + public BasicHttpsBindingElement () + { + } + + public BasicHttpsBindingElement (string name) : base (name) { } + + protected override Type BindingElementType { + get { return typeof (BasicHttpsBinding); } + } + + // Properties + + [ConfigurationProperty ("messageEncoding", + DefaultValue = "Text", + Options = ConfigurationPropertyOptions.None)] + public WSMessageEncoding MessageEncoding { + get { return (WSMessageEncoding) this ["messageEncoding"]; } + set { this ["messageEncoding"] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { + if (_properties == null) { + _properties = base.Properties; + _properties.Add (new ConfigurationProperty ("messageEncoding", typeof (WSMessageEncoding), "Text", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("security", typeof (BasicHttpsSecurityElement), null, null, null, ConfigurationPropertyOptions.None)); + } + return _properties; + } + } + + [ConfigurationProperty ("security", + Options = ConfigurationPropertyOptions.None)] + public BasicHttpsSecurityElement Security { + get { return (BasicHttpsSecurityElement) this ["security"]; } + } + + protected override void OnApplyConfiguration (Binding binding) + { + base.OnApplyConfiguration (binding); + BasicHttpsBinding basicHttpsBinding = (BasicHttpsBinding) binding; + + basicHttpsBinding.MessageEncoding = MessageEncoding; + + basicHttpsBinding.Security.Mode = Security.Mode; + Security.Transport.ApplyConfiguration (basicHttpsBinding.Security.Transport); + } + + protected internal override void InitializeFrom (Binding binding) + { + BasicHttpsBinding b = (BasicHttpsBinding) binding; + base.InitializeFrom (binding); + + MessageEncoding = b.MessageEncoding; + + Security.Mode = b.Security.Mode; + Security.Transport.ApplyConfiguration (b.Security.Transport); + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsSecurityElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsSecurityElement.cs new file mode 100644 index 00000000000..99cc40798c8 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpsSecurityElement.cs @@ -0,0 +1,91 @@ +// +// BasicHttpsSecurityElement.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public sealed class BasicHttpsSecurityElement + : ConfigurationElement + { + // Properties + + [ConfigurationProperty ("message", + Options = ConfigurationPropertyOptions.None)] + public BasicHttpMessageSecurityElement Message { + get { return (BasicHttpMessageSecurityElement) base ["message"]; } + } + + [ConfigurationProperty ("mode", + DefaultValue = "None", + Options = ConfigurationPropertyOptions.None)] + public BasicHttpsSecurityMode Mode { + get { return (BasicHttpsSecurityMode) base ["mode"]; } + set { base ["mode"] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { return base.Properties; } + } + + [ConfigurationProperty ("transport", + Options = ConfigurationPropertyOptions.None)] + public HttpTransportSecurityElement Transport { + get { return (HttpTransportSecurityElement) base ["transport"]; } + } + + + } + +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingsSection.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingsSection.cs index bb6452aeffc..806a63d570f 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingsSection.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingsSection.cs @@ -67,6 +67,14 @@ namespace System.ServiceModel.Configuration get { return (BasicHttpBindingCollectionElement) this ["basicHttpBinding"]; } } +#if NET_4_5 + [ConfigurationProperty ("basicHttpsBinding", + Options = ConfigurationPropertyOptions.None)] + public BasicHttpsBindingCollectionElement BasicHttpsBinding { + get { return (BasicHttpsBindingCollectionElement) this ["basicHttpsBinding"]; } + } +#endif + [MonoTODO ("Not Implemented")] public List BindingCollections { get { throw new NotImplementedException (); } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpBindingBaseElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpBindingBaseElement.cs new file mode 100644 index 00000000000..6aa8ceec31e --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpBindingBaseElement.cs @@ -0,0 +1,232 @@ +// +// HttpBindingBaseElement.cs +// +// This is a .NET 4.5 addition and contains most of the code from +// BasicHttpBindingElement. +// +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public abstract class HttpBindingBaseElement + : StandardBindingElement, IBindingConfigurationElement + { + ConfigurationPropertyCollection _properties; + + public HttpBindingBaseElement () + { + } + + public HttpBindingBaseElement (string name) : base (name) { } + + // Properties + + [ConfigurationProperty ("allowCookies", + DefaultValue = false, + Options = ConfigurationPropertyOptions.None)] + public bool AllowCookies { + get { return (bool) this ["allowCookies"]; } + set { this ["allowCookies"] = value; } + } + + [ConfigurationProperty ("bypassProxyOnLocal", + DefaultValue = false, + Options = ConfigurationPropertyOptions.None)] + public bool BypassProxyOnLocal { + get { return (bool) this ["bypassProxyOnLocal"]; } + set { this ["bypassProxyOnLocal"] = value; } + } + + [ConfigurationProperty ("hostNameComparisonMode", + DefaultValue = "StrongWildcard", + Options = ConfigurationPropertyOptions.None)] + public HostNameComparisonMode HostNameComparisonMode { + get { return (HostNameComparisonMode) this ["hostNameComparisonMode"]; } + set { this ["hostNameComparisonMode"] = value; } + } + + [LongValidator ( MinValue = 0, + MaxValue = 9223372036854775807, + ExcludeRange = false)] + [ConfigurationProperty ("maxBufferPoolSize", + DefaultValue = "524288", + Options = ConfigurationPropertyOptions.None)] + public long MaxBufferPoolSize { + get { return (long) this ["maxBufferPoolSize"]; } + set { this ["maxBufferPoolSize"] = value; } + } + + [IntegerValidator ( MinValue = 1, + MaxValue = int.MaxValue, + ExcludeRange = false)] + [ConfigurationProperty ("maxBufferSize", + DefaultValue = "65536", + Options = ConfigurationPropertyOptions.None)] + public int MaxBufferSize { + get { return (int) this ["maxBufferSize"]; } + set { this ["maxBufferSize"] = value; } + } + + [LongValidator ( MinValue = 1, + MaxValue = 9223372036854775807, + ExcludeRange = false)] + [ConfigurationProperty ("maxReceivedMessageSize", + DefaultValue = "65536", + Options = ConfigurationPropertyOptions.None)] + public long MaxReceivedMessageSize { + get { return (long) this ["maxReceivedMessageSize"]; } + set { this ["maxReceivedMessageSize"] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { + if (_properties == null) { + _properties = base.Properties; + _properties.Add (new ConfigurationProperty ("allowCookies", typeof (bool), "false", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("bypassProxyOnLocal", typeof (bool), "false", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("hostNameComparisonMode", typeof (HostNameComparisonMode), "StrongWildcard", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("maxBufferPoolSize", typeof (long), "524288", null, new LongValidator (0, 9223372036854775807, false), ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("maxBufferSize", typeof (int), "65536", null, new IntegerValidator (1, int.MaxValue, false), ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("maxReceivedMessageSize", typeof (long), "65536", null, new LongValidator (1, 9223372036854775807, false), ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("proxyAddress", typeof (Uri), null, new UriTypeConverter (), null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("readerQuotas", typeof (XmlDictionaryReaderQuotasElement), null, null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("textEncoding", typeof (Encoding), "utf-8", EncodingConverter.Instance, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("transferMode", typeof (TransferMode), "Buffered", null, null, ConfigurationPropertyOptions.None)); + _properties.Add (new ConfigurationProperty ("useDefaultWebProxy", typeof (bool), "true", new BooleanConverter (), null, ConfigurationPropertyOptions.None)); + } + return _properties; + } + } + + [ConfigurationProperty ("proxyAddress", + DefaultValue = null, + Options = ConfigurationPropertyOptions.None)] + public Uri ProxyAddress { + get { return (Uri) this ["proxyAddress"]; } + set { this ["proxyAddress"] = value; } + } + + [ConfigurationProperty ("readerQuotas", + Options = ConfigurationPropertyOptions.None)] + public XmlDictionaryReaderQuotasElement ReaderQuotas { + get { return (XmlDictionaryReaderQuotasElement) this ["readerQuotas"]; } + } + + [TypeConverter (typeof (EncodingConverter))] + [ConfigurationProperty ("textEncoding", + DefaultValue = "utf-8", + Options = ConfigurationPropertyOptions.None)] + public Encoding TextEncoding { + get { return (Encoding) this ["textEncoding"]; } + set { this ["textEncoding"] = value; } + } + + [ConfigurationProperty ("transferMode", + DefaultValue = "Buffered", + Options = ConfigurationPropertyOptions.None)] + public TransferMode TransferMode { + get { return (TransferMode) this ["transferMode"]; } + set { this ["transferMode"] = value; } + } + + [ConfigurationProperty ("useDefaultWebProxy", + DefaultValue = true, + Options = ConfigurationPropertyOptions.None)] + public bool UseDefaultWebProxy { + get { return (bool) this ["useDefaultWebProxy"]; } + set { this ["useDefaultWebProxy"] = value; } + } + + protected override void OnApplyConfiguration (Binding binding) + { + HttpBindingBase basicHttpBinding = (HttpBindingBase) binding; + + basicHttpBinding.AllowCookies = AllowCookies; + basicHttpBinding.BypassProxyOnLocal = BypassProxyOnLocal; + basicHttpBinding.HostNameComparisonMode = HostNameComparisonMode; + basicHttpBinding.MaxBufferPoolSize = MaxBufferPoolSize; + basicHttpBinding.MaxBufferSize = MaxBufferSize; + basicHttpBinding.MaxReceivedMessageSize = MaxReceivedMessageSize; + basicHttpBinding.ProxyAddress = ProxyAddress; + + ReaderQuotas.ApplyConfiguration (basicHttpBinding.ReaderQuotas); + + basicHttpBinding.TextEncoding = TextEncoding; + basicHttpBinding.TransferMode = TransferMode; + basicHttpBinding.UseDefaultWebProxy = UseDefaultWebProxy; + } + + protected internal override void InitializeFrom (Binding binding) + { + HttpBindingBase b = (HttpBindingBase) binding; + + base.InitializeFrom (binding); + AllowCookies = b.AllowCookies; + BypassProxyOnLocal = b.BypassProxyOnLocal; + HostNameComparisonMode = b.HostNameComparisonMode; + MaxBufferPoolSize = b.MaxBufferPoolSize; + MaxBufferSize = b.MaxBufferSize; + MaxReceivedMessageSize = b.MaxReceivedMessageSize; + ProxyAddress = b.ProxyAddress; + + ReaderQuotas.ApplyConfiguration (b.ReaderQuotas); + + TextEncoding = b.TextEncoding; + TransferMode = b.TransferMode; + UseDefaultWebProxy = b.UseDefaultWebProxy; + } + } + +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/CustomPolicyConversionContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/CustomPolicyConversionContext.cs new file mode 100644 index 00000000000..0d20e1befc4 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/CustomPolicyConversionContext.cs @@ -0,0 +1,128 @@ +// +// CustomPolicyConversionContext.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Xml; +using System.ServiceModel.Channels; +using WS = System.Web.Services.Description; + +namespace System.ServiceModel.Description { + + internal class CustomPolicyConversionContext : PolicyConversionContext { + WS.Binding binding; + PolicyAssertionCollection assertions; + BindingElementCollection binding_elements; + + internal WS.Binding WsdlBinding { + get { return binding; } + } + + #region implemented abstract members of PolicyConversionContext + + public override PolicyAssertionCollection GetBindingAssertions () + { + return assertions; + } + + public override PolicyAssertionCollection GetFaultBindingAssertions (FaultDescription fault) + { + throw new NotImplementedException (); + } + + public override PolicyAssertionCollection GetMessageBindingAssertions (MessageDescription message) + { + throw new NotImplementedException (); + } + + public override PolicyAssertionCollection GetOperationBindingAssertions (OperationDescription operation) + { + throw new NotImplementedException (); + } + + public override BindingElementCollection BindingElements { + get { + return binding_elements; + } + } + + #endregion + + public CustomPolicyConversionContext (WS.Binding binding, ServiceEndpoint endpoint) + : base (endpoint) + { + this.binding = binding; + assertions = new PolicyAssertionCollection (); + binding_elements = ((CustomBinding)endpoint.Binding).Elements; + } + + public void AddPolicyAssertion (XmlElement element) + { + /* + * http://www.w3.org/Submission/WS-Policy/#Policy_Assertion: + * + * + * + * ( ( … )* )* + * + * + * + */ + + var exactlyOne = element.FirstChild as XmlElement; + if (exactlyOne == null) { + // OOPS + return; + } + + if (!exactlyOne.NamespaceURI.Equals (Constants.WspNamespace) || + !exactlyOne.LocalName.Equals ("ExactlyOne")) { + // FIXME: What to do with this ... ? + return; + } + + foreach (var node in exactlyOne.ChildNodes) { + var child = node as XmlElement; + if (child == null) + continue; + + if (!child.NamespaceURI.Equals (Constants.WspNamespace) || + !child.LocalName.Equals ("All")) { + // FIXME: Can assertions go here ... ? + continue; + } + + foreach (var node2 in child.ChildNodes) { + var assertion = node2 as XmlElement; + if (assertion == null) + continue; + + assertions.Add (assertion); + } + } + } + } +} + diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataImporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataImporter.cs index febc8527213..2257936225f 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataImporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataImporter.cs @@ -56,7 +56,6 @@ namespace System.ServiceModel.Description policy_extensions.Add (new MessageEncodingBindingElementImporter ()); } - [MonoTODO ("Not in use yet")] public Collection Errors { get { return errors; } } @@ -86,5 +85,40 @@ namespace System.ServiceModel.Description } return (T) value; } + + internal MetadataConversionError AddError (string message, params object[] args) + { + var error = new MetadataConversionError (string.Format (message, args)); + Errors.Add (error); + return error; + } + + internal MetadataConversionError AddWarning (string message, params object[] args) + { + var error = new MetadataConversionError (string.Format (message, args), true); + Errors.Add (error); + return error; + } + + internal class MetadataImportException : Exception + { + public MetadataConversionError Error { + get; + private set; + } + + public MetadataImportException (MetadataConversionError error) + : base (error.Message) + { + this.Error = error; + } + + public MetadataImportException (MetadataConversionError error, Exception inner) + : base (error.Message, inner) + { + this.Error = error; + } + } + } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/PolicyConversionContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/PolicyConversionContext.cs index 368cab78063..5595d01edfc 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/PolicyConversionContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/PolicyConversionContext.cs @@ -36,14 +36,21 @@ namespace System.ServiceModel.Description { public abstract class PolicyConversionContext { + ServiceEndpoint endpoint; + protected PolicyConversionContext (ServiceEndpoint endpoint) { + this.endpoint = endpoint; + } + + internal ServiceEndpoint Endpoint { + get { return endpoint; } } public abstract BindingElementCollection BindingElements { get; } public ContractDescription Contract { - get { throw new NotImplementedException (); } + get { return endpoint.Contract; } } public abstract PolicyAssertionCollection GetBindingAssertions (); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlImporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlImporter.cs index 7cda8c5adf0..c1624220177 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlImporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlImporter.cs @@ -1,11 +1,13 @@ // // WsdlImporter.cs // -// Author: +// Authors: // Atsushi Enomoto // Ankit Jain +// Martin Baulig // // Copyright (C) 2005 Novell, Inc. http://www.novell.com +// Copyright (c) 2012 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 @@ -36,6 +38,7 @@ using System.Xml; using System.Xml.Schema; using SMBinding = System.ServiceModel.Channels.Binding; +using WS = System.Web.Services.Description; using WSServiceDescription = System.Web.Services.Description.ServiceDescription; using WSBinding = System.Web.Services.Description.Binding; using WSMessage = System.Web.Services.Description.Message; @@ -50,6 +53,7 @@ namespace System.ServiceModel.Description XmlSchemaSet xmlschemas; List policies; /* ?? */ MetadataSet metadata; + bool beforeImportCalled; KeyedByTypeCollection wsdl_extensions; @@ -57,6 +61,13 @@ namespace System.ServiceModel.Description Collection contracts = null; ServiceEndpointCollection endpoint_colln = null; + // Contract by PortType + Dictionary contractHash = null; + // ServiceEndpoint by WSBinding + Dictionary bindingHash = null; + // ServiceEndpoint by Port + Dictionary endpointHash = null; + public WsdlImporter ( MetadataSet metadata, IEnumerable policyImportExtensions, @@ -71,7 +82,7 @@ namespace System.ServiceModel.Description wsdl_extensions.Add (new DataContractSerializerMessageContractImporter ()); wsdl_extensions.Add (new XmlSerializerMessageContractImporter ()); - //wsdl_extensions.Add (new MessageEncodingBindingElementImporter ()); + wsdl_extensions.Add (new MessageEncodingBindingElementImporter ()); wsdl_extensions.Add (new TransportBindingElementImporter ()); wsdl_extensions.Add (new StandardBindingImporter ()); } else { @@ -84,6 +95,9 @@ namespace System.ServiceModel.Description this.wsdl_documents = new ServiceDescriptionCollection (); this.xmlschemas = new XmlSchemaSet (); this.policies = new List (); + this.contractHash = new Dictionary (); + this.bindingHash = new Dictionary (); + this.endpointHash = new Dictionary (); foreach (MetadataSection ms in metadata.MetadataSections) { if (ms.Dialect == MetadataSection.ServiceDescriptionDialect && @@ -117,43 +131,164 @@ namespace System.ServiceModel.Description { Collection bindings = new Collection (); - foreach (WSServiceDescription sd in wsdl_documents) - foreach (WSBinding binding in sd.Bindings) - bindings.Add (ImportBinding (binding)); + foreach (WSServiceDescription sd in wsdl_documents) { + foreach (WSBinding binding in sd.Bindings) { + var endpoint = ImportBinding (binding, false); + if (endpoint != null) + bindings.Add (endpoint.Binding); + } + } return bindings; } - public SMBinding ImportBinding (WSBinding binding) + void BeforeImport () { - /* Default, CustomBinding.. */ - CustomBinding smbinding = new CustomBinding (); + if (beforeImportCalled) + return; foreach (IWsdlImportExtension extension in wsdl_extensions) extension.BeforeImport (wsdl_documents, xmlschemas, policies); + + beforeImportCalled = true; + } - smbinding.Name = binding.Name; - smbinding.Namespace = binding.ServiceDescription.TargetNamespace; + public SMBinding ImportBinding (WSBinding binding) + { + return ImportBinding (binding, true).Binding; + } - //FIXME: Added by MessageEncodingBindingElementConverter.ImportPolicy - smbinding.Elements.Add (new TextMessageEncodingBindingElement ()); + ServiceEndpoint ImportBinding (WSBinding binding, bool throwOnError) + { + if (bindingHash.ContainsKey (binding)) { + var sep = bindingHash [binding]; + if (sep != null) + return sep; + + if (!throwOnError) + return null; + + throw new InvalidOperationException (String.Format ( + "Failed to import binding {0}, an error has " + + "already been reported before.", binding.Name)); + } - /*ImportContract - PortType portType = null; - foreach (WSServiceDescription sd in wsdl_documents) { - portType = sd.PortTypes [binding.Type.Name]; - if (portType != null) - break; + try { + var port_type = GetPortTypeFromBinding (binding); + var contract = ImportContract (port_type); + var contract_context = new WsdlContractConversionContext (contract, port_type); + + var sep = ImportBinding (binding, contract_context); + bindingHash.Add (binding, sep); + return sep; + } catch (MetadataImportException) { + bindingHash.Add (binding, null); + if (throwOnError) + throw; + return null; + } catch (Exception ex) { + bindingHash.Add (binding, null); + var error = AddError ( + "Failed to import binding `{0}': {1}", binding.Name, ex.Message); + if (throwOnError) + throw new MetadataImportException (error, ex); + return null; } + } + + ServiceEndpoint ImportBinding (WSBinding binding, + WsdlContractConversionContext contract_context) + { + BeforeImport (); - //FIXME: if portType == null - */ + var sep = new ServiceEndpoint (contract_context.Contract); + + var custom = new CustomBinding (); + custom.Name = binding.Name; + custom.Namespace = binding.ServiceDescription.TargetNamespace; + + sep.Binding = custom; + + try { + ImportPolicy (binding, sep); + } catch (Exception ex) { + // FIXME: Policy import is still experimental. + AddWarning ("Exception while trying to import policy for " + + "binding `{0}': {1}", binding.Name, ex.Message); + } + + var endpoint_context = new WsdlEndpointConversionContext ( + contract_context, sep, null, binding); + + foreach (IWsdlImportExtension extension in wsdl_extensions) + extension.ImportEndpoint (this, endpoint_context); - // FIXME: ImportContract here.. + return sep; + } + + void ImportPolicy (WSBinding binding, ServiceEndpoint endpoint) + { + var context = new Description.CustomPolicyConversionContext (binding, endpoint); + var assertions = context.GetBindingAssertions (); + + foreach (var ext in binding.Extensions) { + var xml = ext as XmlElement; + if (xml == null) + continue; + if (!xml.NamespaceURI.Equals (Constants.WspNamespace)) + continue; + if (!xml.LocalName.Equals ("PolicyReference")) + continue; + var uri = xml.GetAttribute ("URI"); + + if (!uri.StartsWith ("#")) { + // FIXME + AddWarning ( + "Failed to resolve unknown policy reference `{0}' for " + + "binding `{1}'.", uri, binding.Name); + continue; + } + + foreach (var sext in binding.ServiceDescription.Extensions) { + var sxml = sext as XmlElement; + if (sxml == null) + continue; + if (!sxml.NamespaceURI.Equals (Constants.WspNamespace)) + continue; + if (!sxml.LocalName.Equals ("Policy")) + continue; + var id = sxml.GetAttribute ("Id", Constants.WsuNamespace); + if (!uri.Substring (1).Equals (id)) + continue; + context.AddPolicyAssertion (sxml); + } + } - return smbinding; + foreach (IPolicyImportExtension extension in PolicyImportExtensions) { + try { + extension.ImportPolicy (this, context); + } catch (Exception ex) { + AddWarning ( + "PolicyImportException `{0}' threw an exception while " + + "trying to import policy references for endpoint `{1}': {2}", + extension.GetType ().Name, endpoint.Name, ex.Message); + } + } } + PortType GetPortTypeFromBinding (WSBinding binding) + { + foreach (WSServiceDescription sd in wsdl_documents) { + var port_type = sd.PortTypes [binding.Type.Name]; + if (port_type != null) + return port_type; + } + + throw new MetadataImportException (AddError ( + "PortType named {0} not found in namespace {1}.", + binding.Type.Name, binding.Type.Namespace)); + } + public override Collection ImportAllContracts () { if (contracts != null) @@ -162,8 +297,11 @@ namespace System.ServiceModel.Description contracts = new Collection (); foreach (WSServiceDescription sd in wsdl_documents) { - foreach (PortType pt in sd.PortTypes) - contracts.Add (ImportContract (pt)); + foreach (PortType pt in sd.PortTypes) { + var cd = ImportContract (pt, false); + if (cd != null) + contracts.Add (cd); + } } return contracts; @@ -176,24 +314,63 @@ namespace System.ServiceModel.Description endpoint_colln = new ServiceEndpointCollection (); - foreach (IWsdlImportExtension extension in wsdl_extensions) { - extension.BeforeImport (wsdl_documents, xmlschemas, policies); + foreach (WSServiceDescription wsd in wsdl_documents) { + foreach (Service service in wsd.Services) { + foreach (Port port in service.Ports) { + var sep = ImportEndpoint (port, false); + if (sep != null) + endpoint_colln.Add (sep); + } + } } - foreach (WSServiceDescription wsd in wsdl_documents) - foreach (Service service in wsd.Services) - foreach (Port port in service.Ports) - endpoint_colln.Add (ImportEndpoint (port)); - return endpoint_colln; } public ContractDescription ImportContract (PortType wsdlPortType) { - foreach (IWsdlImportExtension extension in wsdl_extensions) { - extension.BeforeImport (wsdl_documents, xmlschemas, policies); + return ImportContract (wsdlPortType, true); + } + + ContractDescription ImportContract (PortType portType, bool throwOnError) + { + if (contractHash.ContainsKey (portType)) { + var cd = contractHash [portType]; + if (cd != null) + return cd; + + if (!throwOnError) + return null; + + throw new InvalidOperationException (String.Format ( + "Failed to import contract for port type `{0}', " + + "an error has already been reported.", portType.Name)); } + try { + var cd = DoImportContract (portType); + contractHash.Add (portType, cd); + return cd; + } catch (MetadataImportException) { + contractHash.Add (portType, null); + if (throwOnError) + throw; + return null; + } catch (Exception ex) { + contractHash.Add (portType, null); + var error = AddError ( + "Failed to import contract for port type `{0}': {1}", + portType.Name, ex.Message); + if (throwOnError) + throw new MetadataImportException (error, ex); + return null; + } + } + + ContractDescription DoImportContract (PortType wsdlPortType) + { + BeforeImport (); + ContractDescription cd = new ContractDescription (wsdlPortType.Name, wsdlPortType.ServiceDescription.TargetNamespace); foreach (Operation op in wsdlPortType.Operations) { @@ -265,61 +442,140 @@ namespace System.ServiceModel.Description public ServiceEndpoint ImportEndpoint (Port wsdlPort) { - foreach (IWsdlImportExtension extension in wsdl_extensions) { - extension.BeforeImport (wsdl_documents, xmlschemas, policies); + return ImportEndpoint (wsdlPort, true); + } + + ServiceEndpoint ImportEndpoint (Port port, bool throwOnError) + { + ServiceEndpoint endpoint; + if (endpointHash.ContainsKey (port)) { + endpoint = endpointHash [port]; + if (endpoint != null) + return endpoint; + + if (!throwOnError) + return null; + + throw new InvalidOperationException (String.Format ( + "Failed to import port `{0}', an error has " + + "already been reported before.", port.Name)); } - //Get the corresponding contract - //via the PortType - WSBinding wsb = wsdlPort.Service.ServiceDescription.Bindings [wsdlPort.Binding.Name]; - if (wsb == null) - //FIXME - throw new Exception (String.Format ("Binding named {0} not found.", wsdlPort.Binding.Name)); + var binding = port.Service.ServiceDescription.Bindings [port.Binding.Name]; + if (binding == null) { + endpointHash.Add (port, null); + var error = AddError ( + "Failed to import port `{0}': cannot find binding `{1}' that " + + "this port depends on.", port.Name, port.Binding.Name); + if (throwOnError) + throw new MetadataImportException (error); + return null; + } - SMBinding binding = ImportBinding (wsb); + try { + endpoint = ImportBinding (binding, throwOnError); + } catch (Exception ex) { + endpointHash.Add (port, null); + var error = AddError ( + "Failed to import port `{0}': error while trying to import " + + "binding `{1}' that this port depends on: {2}", + port.Name, port.Binding.Name, ex.Message); + if (throwOnError) + throw new MetadataImportException (error, ex); + return null; + } - PortType port_type = null; - foreach (WSServiceDescription sd in wsdl_documents) { - port_type = sd.PortTypes [wsb.Type.Name]; - if (port_type != null) - break; + if (endpoint == null) { + endpointHash.Add (port, null); + AddError ( + "Failed to import port `{0}': error while trying to import " + + "binding `{1}' that this port depends on.", + port.Name, port.Binding.Name); + return null; } - if (port_type == null) - //FIXME - throw new Exception (String.Format ("PortType named {0} not found.", wsb.Type.Name)); + try { + ImportEndpoint (port, binding, endpoint, throwOnError); + endpointHash.Add (port, endpoint); + return endpoint; + } catch (MetadataImportException) { + endpointHash.Add (port, null); + if (throwOnError) + throw; + return null; + } catch (Exception ex) { + endpointHash.Add (port, null); + var error = AddError ( + "Failed to import port `{0}': {1}", port.Name, ex.Message); + if (throwOnError) + throw new MetadataImportException (error, ex); + return null; + } + } - ContractDescription contract = ImportContract (port_type); - ServiceEndpoint sep = new ServiceEndpoint (contract); + void ImportEndpoint (Port port, WSBinding wsb, ServiceEndpoint sep, bool throwOnError) + { + BeforeImport (); - sep.Binding = binding; + var port_type = GetPortTypeFromBinding (wsb); - WsdlContractConversionContext contract_context = new WsdlContractConversionContext (contract, port_type); + var contract_context = new WsdlContractConversionContext (sep.Contract, port_type); WsdlEndpointConversionContext endpoint_context = new WsdlEndpointConversionContext ( - contract_context, sep, wsdlPort, wsb); + contract_context, sep, port, wsb); foreach (IWsdlImportExtension extension in wsdl_extensions) extension.ImportEndpoint (this, endpoint_context); + } - return sep; + void ImportEndpoints (ServiceEndpointCollection coll, WSBinding binding) + { + foreach (WSServiceDescription wsd in wsdl_documents) { + foreach (WS.Service service in wsd.Services) { + foreach (WS.Port port in service.Ports) { + if (!binding.Name.Equals (port.Binding.Name)) + continue; + var sep = ImportEndpoint (port, false); + if (sep != null) + coll.Add (sep); + } + } + } } - public ServiceEndpointCollection ImportEndpoints ( - WSBinding binding) + public ServiceEndpointCollection ImportEndpoints (WSBinding binding) { - throw new NotImplementedException (); + var coll = new ServiceEndpointCollection (); + ImportEndpoints (coll, binding); + return coll; } - public ServiceEndpointCollection ImportEndpoints ( - PortType portType) + public ServiceEndpointCollection ImportEndpoints (PortType portType) { - throw new NotImplementedException (); + var coll = new ServiceEndpointCollection (); + + foreach (WSServiceDescription wsd in wsdl_documents) { + foreach (WS.Binding binding in wsd.Bindings) { + if (!binding.Type.Name.Equals (portType.Name)) + continue; + + ImportEndpoints (coll, binding); + } + } + + return coll; } - public ServiceEndpointCollection ImportEndpoints ( - Service service) + public ServiceEndpointCollection ImportEndpoints (Service service) { - throw new NotImplementedException (); + var coll = new ServiceEndpointCollection (); + + foreach (Port port in service.Ports) { + var sep = ImportEndpoint (port, false); + if (sep != null) + coll.Add (sep); + } + + return coll; } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources index 36ce3418672..8baeb0a5ecd 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources @@ -257,6 +257,7 @@ System.ServiceModel.Channels/PeerInputChannel.cs System.ServiceModel.Channels/PeerOutputChannel.cs System.ServiceModel.Channels/PeerTransportBindingElement.cs System.ServiceModel.Channels/PnrpPeerResolverBindingElement.cs +System.ServiceModel.Channels/PolicyImportHelper.cs System.ServiceModel.Channels/PrivacyNoticeBindingElement.cs System.ServiceModel.Channels/ReliableSessionBindingElement.cs System.ServiceModel.Channels/ReliableSessionBindingElementImporter.cs @@ -558,6 +559,7 @@ System.ServiceModel.Description/ClientCredentials.cs System.ServiceModel.Description/ClientViaBehavior.cs System.ServiceModel.Description/ContractDescription.cs System.ServiceModel.Description/ContractDescriptionGenerator.cs +System.ServiceModel.Description/CustomPolicyConversionContext.cs System.ServiceModel.Description/DataContractSerializerMessageContractImporter.cs System.ServiceModel.Description/DataContractSerializerOperationBehavior.cs System.ServiceModel.Description/FaultDescription.cs diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/AllEnums.cs b/mcs/class/System.ServiceModel/System.ServiceModel/AllEnums.cs index 262abe47914..5beb4fe9022 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/AllEnums.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/AllEnums.cs @@ -74,6 +74,14 @@ namespace System.ServiceModel TransportCredentialOnly, } +#if NET_4_5 + public enum BasicHttpsSecurityMode + { + Transport, + TransportWithMessageCredential + } +#endif + public enum CommunicationState { Created, diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs index 2ed2da27b4d..b3607f3d55a 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs @@ -1,6 +1,9 @@ // // BasicHttpBinding.cs // +// See BasicHttpBinding_4_5.cs and HttpBindingBase.cs for the .NET 4.5 +// version of this class. +// // Author: // Atsushi Enomoto // @@ -26,6 +29,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !NET_4_5 using System; using System.Collections.Generic; using System.Net; @@ -310,3 +314,4 @@ namespace System.ServiceModel } } } +#endif diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding_4_5.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding_4_5.cs new file mode 100644 index 00000000000..276e92e56e6 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding_4_5.cs @@ -0,0 +1,196 @@ +// +// BasicHttpBinding_4_5.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com +// Copyright 2011-2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Security; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.Text; +using System.Xml; +using System.ServiceModel.Configuration; + +namespace System.ServiceModel +{ + public class BasicHttpBinding : HttpBindingBase, + IBindingRuntimePreferences + { + WSMessageEncoding message_encoding = WSMessageEncoding.Text; + BasicHttpSecurity security; + + public BasicHttpBinding () + : this (BasicHttpSecurityMode.None) + { + } + + public BasicHttpBinding (string configurationName) + : this () + { + BindingsSection bindingsSection = ConfigUtil.BindingsSection; + BasicHttpBindingElement el = + bindingsSection.BasicHttpBinding.Bindings [configurationName]; + + el.ApplyConfiguration (this); + } + + public BasicHttpBinding ( + BasicHttpSecurityMode securityMode) + { + security = new BasicHttpSecurity (securityMode); + } + + public WSMessageEncoding MessageEncoding { + get { return message_encoding; } + set { message_encoding = value; } + } + + public override string Scheme { + get { + switch (Security.Mode) { + case BasicHttpSecurityMode.Transport: + case BasicHttpSecurityMode.TransportWithMessageCredential: + return Uri.UriSchemeHttps; + default: + return Uri.UriSchemeHttp; + } + } + } + + public BasicHttpSecurity Security { + get { return security; } + } + + public override BindingElementCollection + CreateBindingElements () + { + var list = new List (); + + var security = CreateSecurityBindingElement (); + if (security != null) + list.Add (security); + + list.Add (BuildMessageEncodingBindingElement ()); + list.Add (GetTransport ()); + + return new BindingElementCollection (list.ToArray ()); + } + + SecurityBindingElement CreateSecurityBindingElement () + { + SecurityBindingElement element; + switch (Security.Mode) { + case BasicHttpSecurityMode.Message: + if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate) + throw new InvalidOperationException ("When Message security is enabled in a BasicHttpBinding, the message security credential type must be BasicHttpMessageCredentialType.Certificate."); + element = SecurityBindingElement.CreateMutualCertificateBindingElement ( + MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); + break; + + case BasicHttpSecurityMode.TransportWithMessageCredential: + if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate) + // FIXME: pass proper security token parameters. + element = SecurityBindingElement.CreateCertificateOverTransportBindingElement (); + else + element = new AsymmetricSecurityBindingElement (); + break; + default: + return null; + } + + element.SetKeyDerivation (false); + element.SecurityHeaderLayout = SecurityHeaderLayout.Lax; + return element; + } + + MessageEncodingBindingElement BuildMessageEncodingBindingElement () + { + if (MessageEncoding == WSMessageEncoding.Text) { + TextMessageEncodingBindingElement tm = new TextMessageEncodingBindingElement ( + MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding); + ReaderQuotas.CopyTo (tm.ReaderQuotas); + return tm; + } else { + return new MtomMessageEncodingBindingElement ( + MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding); + } + } + + TransportBindingElement GetTransport () + { + HttpTransportBindingElement h; + switch (Security.Mode) { + case BasicHttpSecurityMode.Transport: + case BasicHttpSecurityMode.TransportWithMessageCredential: + h = new HttpsTransportBindingElement (); + break; + default: + h = new HttpTransportBindingElement (); + break; + } + + h.AllowCookies = AllowCookies; + h.BypassProxyOnLocal = BypassProxyOnLocal; + h.HostNameComparisonMode = HostNameComparisonMode; + h.MaxBufferPoolSize = MaxBufferPoolSize; + h.MaxBufferSize = MaxBufferSize; + h.MaxReceivedMessageSize = MaxReceivedMessageSize; + h.ProxyAddress = ProxyAddress; + h.UseDefaultWebProxy = UseDefaultWebProxy; + h.TransferMode = TransferMode; + h.ExtendedProtectionPolicy = Security.Transport.ExtendedProtectionPolicy; + + switch (Security.Transport.ClientCredentialType) { + case HttpClientCredentialType.Basic: + h.AuthenticationScheme = AuthenticationSchemes.Basic; + break; + case HttpClientCredentialType.Ntlm: + h.AuthenticationScheme = AuthenticationSchemes.Ntlm; + break; + case HttpClientCredentialType.Windows: + h.AuthenticationScheme = AuthenticationSchemes.Negotiate; + break; + case HttpClientCredentialType.Digest: + h.AuthenticationScheme = AuthenticationSchemes.Digest; + break; + case HttpClientCredentialType.Certificate: + switch (Security.Mode) { + case BasicHttpSecurityMode.Transport: + (h as HttpsTransportBindingElement).RequireClientCertificate = true; + break; + case BasicHttpSecurityMode.TransportCredentialOnly: + throw new InvalidOperationException ("Certificate-based client authentication is not supported by 'TransportCredentialOnly' mode."); + } + break; + } + + return h; + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs new file mode 100644 index 00000000000..6ac63100051 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsBinding.cs @@ -0,0 +1,166 @@ +// +// BasicHttpsBinding.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com +// Copyright 2011-2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Security; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.Text; +using System.Xml; +using System.ServiceModel.Configuration; + +namespace System.ServiceModel +{ + public class BasicHttpsBinding : HttpBindingBase, + IBindingRuntimePreferences + { + WSMessageEncoding message_encoding = WSMessageEncoding.Text; + BasicHttpsSecurity security; + + public BasicHttpsBinding () + : this (BasicHttpsSecurityMode.Transport) + { + } + + public BasicHttpsBinding (string configurationName) + : this () + { + BindingsSection bindingsSection = ConfigUtil.BindingsSection; + BasicHttpsBindingElement el = + bindingsSection.BasicHttpsBinding.Bindings [configurationName]; + + el.ApplyConfiguration (this); + } + + public BasicHttpsBinding ( + BasicHttpsSecurityMode securityMode) + { + security = new BasicHttpsSecurity (securityMode); + } + + public WSMessageEncoding MessageEncoding { + get { return message_encoding; } + set { message_encoding = value; } + } + + public override string Scheme { + get { return Uri.UriSchemeHttps; } + } + + public BasicHttpsSecurity Security { + get { return security; } + } + + public override BindingElementCollection + CreateBindingElements () + { + var list = new List (); + + var security = CreateSecurityBindingElement (); + if (security != null) + list.Add (security); + + list.Add (BuildMessageEncodingBindingElement ()); + list.Add (GetTransport ()); + + return new BindingElementCollection (list.ToArray ()); + } + + SecurityBindingElement CreateSecurityBindingElement () + { + SecurityBindingElement element; + switch (Security.Mode) { + case BasicHttpsSecurityMode.TransportWithMessageCredential: + if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate) + // FIXME: pass proper security token parameters. + element = SecurityBindingElement.CreateCertificateOverTransportBindingElement (); + else + element = new AsymmetricSecurityBindingElement (); + break; + default: + return null; + } + + element.SetKeyDerivation (false); + element.SecurityHeaderLayout = SecurityHeaderLayout.Lax; + return element; + } + + MessageEncodingBindingElement BuildMessageEncodingBindingElement () + { + if (MessageEncoding == WSMessageEncoding.Text) { + TextMessageEncodingBindingElement tm = new TextMessageEncodingBindingElement ( + MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding); + ReaderQuotas.CopyTo (tm.ReaderQuotas); + return tm; + } else { + return new MtomMessageEncodingBindingElement ( + MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding); + } + } + + TransportBindingElement GetTransport () + { + HttpsTransportBindingElement h = new HttpsTransportBindingElement (); + + h.AllowCookies = AllowCookies; + h.BypassProxyOnLocal = BypassProxyOnLocal; + h.HostNameComparisonMode = HostNameComparisonMode; + h.MaxBufferPoolSize = MaxBufferPoolSize; + h.MaxBufferSize = MaxBufferSize; + h.MaxReceivedMessageSize = MaxReceivedMessageSize; + h.ProxyAddress = ProxyAddress; + h.UseDefaultWebProxy = UseDefaultWebProxy; + h.TransferMode = TransferMode; + h.ExtendedProtectionPolicy = Security.Transport.ExtendedProtectionPolicy; + + switch (Security.Transport.ClientCredentialType) { + case HttpClientCredentialType.Basic: + h.AuthenticationScheme = AuthenticationSchemes.Basic; + break; + case HttpClientCredentialType.Ntlm: + h.AuthenticationScheme = AuthenticationSchemes.Ntlm; + break; + case HttpClientCredentialType.Windows: + h.AuthenticationScheme = AuthenticationSchemes.Negotiate; + break; + case HttpClientCredentialType.Digest: + h.AuthenticationScheme = AuthenticationSchemes.Digest; + break; + case HttpClientCredentialType.Certificate: + h.RequireClientCertificate = true; + break; + } + + return h; + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs new file mode 100644 index 00000000000..a77099eaf67 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpsSecurity.cs @@ -0,0 +1,62 @@ +// +// BasicHttpsSecurity.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright 2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Net.Security; +using System.ServiceModel.Channels; + +namespace System.ServiceModel +{ + public sealed class BasicHttpsSecurity + { + internal BasicHttpsSecurity (BasicHttpsSecurityMode mode) + { + this.mode = mode; + this.message = new BasicHttpMessageSecurity (); + this.transport = new HttpTransportSecurity (); + } + + BasicHttpMessageSecurity message; + BasicHttpsSecurityMode mode; + HttpTransportSecurity transport; + + public BasicHttpMessageSecurity Message { + get { return message; } + } + + public BasicHttpsSecurityMode Mode { + get { return mode; } + set { mode = value; } + } + + public HttpTransportSecurity Transport { + get { return transport; } + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs index 0752a48aaa8..62a0ac1499d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs @@ -361,7 +361,7 @@ namespace System.ServiceModel public object [] Results { get; private set; } } -#if NET_2_1 +#if NET_2_1 || NET_4_0 protected internal #else internal diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs new file mode 100644 index 00000000000..2e486b897ea --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/HttpBindingBase.cs @@ -0,0 +1,143 @@ +// +// HttpBindingBase.cs +// +// Authors: +// Atsushi Enomoto +// Martin Baulig +// +// Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com +// Copyright 2011-2012 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Security; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.Text; +using System.Xml; +using System.ServiceModel.Configuration; + +namespace System.ServiceModel +{ + public abstract class HttpBindingBase : Binding, + IBindingRuntimePreferences + { + bool allow_cookies, bypass_proxy_on_local; + HostNameComparisonMode host_name_comparison_mode + = HostNameComparisonMode.StrongWildcard; + long max_buffer_pool_size = 0x80000; + int max_buffer_size = 0x10000; + long max_recv_message_size = 0x10000; + Uri proxy_address; + XmlDictionaryReaderQuotas reader_quotas + = new XmlDictionaryReaderQuotas (); + EnvelopeVersion env_version = EnvelopeVersion.Soap11; + Encoding text_encoding = new UTF8Encoding (); + TransferMode transfer_mode + = TransferMode.Buffered; + bool use_default_web_proxy = true; + + public bool AllowCookies { + get { return allow_cookies; } + set { allow_cookies = value; } + } + + public bool BypassProxyOnLocal { + get { return bypass_proxy_on_local; } + set { bypass_proxy_on_local = value; } + } + + public HostNameComparisonMode HostNameComparisonMode { + get { return host_name_comparison_mode; } + set { host_name_comparison_mode = value; } + } + + public long MaxBufferPoolSize { + get { return max_buffer_pool_size; } + set { + if (value <= 0) + throw new ArgumentOutOfRangeException (); + max_buffer_pool_size = value; + } + } + + public int MaxBufferSize { + get { return max_buffer_size; } + set { + if (value <= 0) + throw new ArgumentOutOfRangeException (); + max_buffer_size = value; + } + } + + public long MaxReceivedMessageSize { + get { return max_recv_message_size; } + set { + if (value <= 0) + throw new ArgumentOutOfRangeException (); + max_recv_message_size = value; + } + } + + public Uri ProxyAddress { + get { return proxy_address; } + set { proxy_address = value; } + } + + public XmlDictionaryReaderQuotas ReaderQuotas { + get { return reader_quotas; } + set { reader_quotas = value; } + } + + public override abstract string Scheme { + get; + } + + public EnvelopeVersion EnvelopeVersion { + get { return env_version; } + } + + public Encoding TextEncoding { + get { return text_encoding; } + set { text_encoding = value; } + } + + public TransferMode TransferMode { + get { return transfer_mode; } + set { transfer_mode = value; } + } + + public bool UseDefaultWebProxy { + get { return use_default_web_proxy; } + set { use_default_web_proxy = value; } + } + + public override abstract BindingElementCollection CreateBindingElements (); + + // explicit interface implementations + + bool IBindingRuntimePreferences.ReceiveSynchronously { + get { return false; } + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs b/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs index c99b341052f..223faff637c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/NetTcpBinding.cs @@ -45,7 +45,7 @@ namespace System.ServiceModel XmlDictionaryReaderQuotas reader_quotas; bool transaction_flow; TransactionProtocol transaction_protocol; - TcpTransportBindingElement transport = new TcpTransportBindingElement (); + TcpTransportBindingElement transport; public NetTcpBinding () : this (SecurityMode.Transport) @@ -61,6 +61,15 @@ namespace System.ServiceModel bool reliableSessionEnabled) { security = new NetTcpSecurity (securityMode); + transport = new TcpTransportBindingElement (); + } + + internal NetTcpBinding (TcpTransportBindingElement transport, + NetTcpSecurity security, + bool reliableSessionEnabled) + { + this.transport = transport; + this.security = security; } public HostNameComparisonMode HostNameComparisonMode { @@ -223,8 +232,14 @@ namespace System.ServiceModel BindingElement CreateTransportSecurity () { switch (Security.Mode) { - case SecurityMode.None: - case SecurityMode.Message: + case SecurityMode.Transport: + return new WindowsStreamSecurityBindingElement () { + ProtectionLevel = Security.Transport.ProtectionLevel }; + + case SecurityMode.TransportWithMessageCredential: + return new SslStreamSecurityBindingElement (); + + default: return null; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources index bd6d6c3438e..153d9daa412 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources @@ -200,3 +200,12 @@ System.ServiceModel/TransactionProtocolTest.cs System.ServiceModel/UriSchemeKeyedCollectionTest.cs System.ServiceModel/WSFederationHttpBindingTest.cs System.ServiceModel/WSHttpBindingTest.cs +MetadataTests/BindingTestAssertions.cs +MetadataTests/MiscImportTests.cs +MetadataTests/ImportTests.cs +MetadataTests/ImportTests_CreateMetadata.cs +MetadataTests/ImportTests_LoadMetadata.cs +MetadataTests/ImportTests_RoundTrip.cs +MetadataTests/MetadataSamples.cs +MetadataTests/TestContext.cs +MetadataTests/TestLabel.cs diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/AssemblyInfo.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/AssemblyInfo.cs new file mode 100644 index 00000000000..6b4eab17255 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/AssemblyInfo.cs @@ -0,0 +1,52 @@ +// +// AssemblyInfo.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("MetadataTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Xamarin")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Xamarin Inc. (http://www.xamarin.com)")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/BindingTestAssertions.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/BindingTestAssertions.cs new file mode 100644 index 00000000000..33021156ab3 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/BindingTestAssertions.cs @@ -0,0 +1,584 @@ +// +// Test.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Net; +using System.Net.Security; +using System.Xml; +using System.Text; +using System.Collections.Generic; +using System.ServiceModel; +using System.ServiceModel.Security; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using NUnit.Framework; +using NUnit.Framework.Constraints; +using NUnit.Framework.SyntaxHelpers; + +using WS = System.Web.Services.Description; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public static class BindingTestAssertions { + + const string WspNamespace = "http://schemas.xmlsoap.org/ws/2004/09/policy"; + + public static void CheckImportErrors (WsdlImporter importer, TestLabel label) + { + bool foundErrors = false; + foreach (var error in importer.Errors) { + if (error.IsWarning) + Console.WriteLine ("WARNING ({0}): {1}", label, error.Message); + else { + Console.WriteLine ("ERROR ({0}): {1}", label, error.Message); + foundErrors = true; + } + } + + if (foundErrors) + Assert.Fail ("Found import errors", label); + } + + static void CheckSoapBinding (object extension, string transport, TestLabel label) + { + label.EnterScope ("soap"); + Assert.That (extension, Is.InstanceOfType (typeof (WS.SoapBinding)), label.Get ()); + var soap = (WS.SoapBinding)extension; + Assert.That (soap.Style, Is.EqualTo (WS.SoapBindingStyle.Document), label.Get ()); + Assert.That (soap.Transport, Is.EqualTo (transport), label.Get ()); + Assert.That (soap.Required, Is.False, label.Get ()); + label.LeaveScope (); + } + + public static void CheckBasicHttpBinding ( + Binding binding, string scheme, BasicHttpSecurityMode security, + WSMessageEncoding encoding, HttpClientCredentialType clientCred, + AuthenticationSchemes authScheme, TestLabel label) + { + label.EnterScope ("http"); + + if (security == BasicHttpSecurityMode.Message) { + Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ()); + } else { + Assert.That (binding, Is.InstanceOfType (typeof(BasicHttpBinding)), label.Get ()); + var basicHttp = (BasicHttpBinding)binding; + Assert.That (basicHttp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap11), label.Get ()); + Assert.That (basicHttp.MessageVersion, Is.EqualTo (MessageVersion.Soap11), label.Get ()); + Assert.That (basicHttp.Scheme, Is.EqualTo (scheme), label.Get ()); + Assert.That (basicHttp.TransferMode, Is.EqualTo (TransferMode.Buffered), label.Get ()); + Assert.That (basicHttp.MessageEncoding, Is.EqualTo (encoding), label.Get ()); + Assert.That (basicHttp.Security, Is.Not.Null, label.Get ()); + Assert.That (basicHttp.Security.Mode, Is.EqualTo (security), label.Get ()); + Assert.That (basicHttp.Security.Transport.ClientCredentialType, Is.EqualTo (clientCred), label.Get ()); + Assert.That (basicHttp.Security.Message.AlgorithmSuite, Is.EqualTo (SecurityAlgorithmSuite.Basic256), label.Get ()); + } + + label.EnterScope ("elements"); + + var elements = binding.CreateBindingElements (); + Assert.That (elements, Is.Not.Null, label.Get ()); + if ((security == BasicHttpSecurityMode.Message) || + (security == BasicHttpSecurityMode.TransportWithMessageCredential)) + Assert.That (elements.Count, Is.EqualTo (3), label.Get ()); + else + Assert.That (elements.Count, Is.EqualTo (2), label.Get ()); + + TextMessageEncodingBindingElement textElement = null; + TransportSecurityBindingElement securityElement = null; + HttpTransportBindingElement transportElement = null; + AsymmetricSecurityBindingElement asymmSecurityElement = null; + MtomMessageEncodingBindingElement mtomElement = null; + + foreach (var element in elements) { + if (element is TextMessageEncodingBindingElement) + textElement = (TextMessageEncodingBindingElement)element; + else if (element is HttpTransportBindingElement) + transportElement = (HttpTransportBindingElement)element; + else if (element is TransportSecurityBindingElement) + securityElement = (TransportSecurityBindingElement)element; + else if (element is AsymmetricSecurityBindingElement) + asymmSecurityElement = (AsymmetricSecurityBindingElement)element; + else if (element is MtomMessageEncodingBindingElement) + mtomElement = (MtomMessageEncodingBindingElement)element; + else + Assert.Fail (string.Format ( + "Unknown element: {0}", element.GetType ()), label.Get ()); + } + + label.EnterScope ("text"); + if (encoding == WSMessageEncoding.Text) { + Assert.That (textElement, Is.Not.Null, label.Get ()); + Assert.That (textElement.WriteEncoding, Is.InstanceOfType (typeof(UTF8Encoding)), label.Get ()); + } else { + Assert.That (textElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("mtom"); + if (encoding == WSMessageEncoding.Mtom) { + Assert.That (mtomElement, Is.Not.Null, label.Get ()); + } else { + Assert.That (mtomElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("security"); + if (security == BasicHttpSecurityMode.TransportWithMessageCredential) { + Assert.That (securityElement, Is.Not.Null, label.Get ()); + Assert.That (securityElement.SecurityHeaderLayout, + Is.EqualTo (SecurityHeaderLayout.Lax), label.Get ()); + } else { + Assert.That (securityElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("asymmetric"); + if (security == BasicHttpSecurityMode.Message) { + Assert.That (asymmSecurityElement, Is.Not.Null, label.Get ()); + } else { + Assert.That (asymmSecurityElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("transport"); + Assert.That (transportElement, Is.Not.Null, label.Get ()); + + Assert.That (transportElement.Realm, Is.Empty, label.Get ()); + Assert.That (transportElement.Scheme, Is.EqualTo (scheme), label.Get ()); + Assert.That (transportElement.TransferMode, Is.EqualTo (TransferMode.Buffered), label.Get ()); + + label.EnterScope ("auth"); + Assert.That (transportElement.AuthenticationScheme, Is.EqualTo (authScheme), label.Get ()); + label.LeaveScope (); // auth + label.LeaveScope (); // transport + label.LeaveScope (); // elements + label.LeaveScope (); // http + } + + static void CheckEndpoint (ServiceEndpoint endpoint, string uri, TestLabel label) + { + label.EnterScope ("endpoint"); + Assert.That (endpoint.ListenUri, Is.EqualTo (new Uri (uri)), label.Get ()); + Assert.That (endpoint.ListenUriMode, Is.EqualTo (ListenUriMode.Explicit), label.Get ()); + Assert.That (endpoint.Contract, Is.Not.Null, label.Get ()); + Assert.That (endpoint.Contract.Name, Is.EqualTo ("MyContract"), label.Get ()); + Assert.That (endpoint.Address, Is.Not.Null, label.Get ()); + Assert.That (endpoint.Address.Uri, Is.EqualTo (new Uri (uri)), label.Get ()); + Assert.That (endpoint.Address.Identity, Is.Null, label.Get ()); + Assert.That (endpoint.Address.Headers, Is.Not.Null, label.Get ()); + Assert.That (endpoint.Address.Headers.Count, Is.EqualTo (0), label.Get ()); + label.LeaveScope (); + } + + public static void BasicHttpBinding ( + TestContext context, MetadataSet doc, WSMessageEncoding encoding, TestLabel label) + { + BasicHttpBinding ( + context, doc, BasicHttpSecurityMode.None, encoding, + HttpClientCredentialType.None, AuthenticationSchemes.Anonymous, + label); + } + + public static void BasicHttpBinding ( + TestContext context, MetadataSet doc, BasicHttpSecurityMode security, TestLabel label) + { + BasicHttpBinding ( + context, doc, security, WSMessageEncoding.Text, + HttpClientCredentialType.None, AuthenticationSchemes.Anonymous, + label); + } + + public static void BasicHttpBinding ( + TestContext context, MetadataSet doc, BasicHttpSecurityMode security, + WSMessageEncoding encoding, HttpClientCredentialType clientCred, + AuthenticationSchemes authScheme, TestLabel label) + { + label.EnterScope ("basicHttpBinding"); + + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + label.EnterScope ("bindings"); + Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ()); + + var binding = sd.Bindings [0]; + Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ()); + Assert.That (binding.Extensions, Is.Not.Null, label.Get ()); + + bool hasPolicyXml; + + switch (security) { + case BasicHttpSecurityMode.None: + hasPolicyXml = encoding == WSMessageEncoding.Mtom; + break; + case BasicHttpSecurityMode.Message: + case BasicHttpSecurityMode.Transport: + case BasicHttpSecurityMode.TransportWithMessageCredential: + if (encoding == WSMessageEncoding.Mtom) + throw new InvalidOperationException (); + hasPolicyXml = true; + break; + case BasicHttpSecurityMode.TransportCredentialOnly: + hasPolicyXml = true; + break; + default: + throw new InvalidOperationException (); + } + label.LeaveScope (); + + WS.SoapBinding soap = null; + XmlElement xml = null; + + foreach (var ext in binding.Extensions) { + if (ext is WS.SoapBinding) + soap = (WS.SoapBinding)ext; + else if (ext is XmlElement) + xml = (XmlElement)ext; + } + + CheckSoapBinding (soap, WS.SoapBinding.HttpTransport, label); + label.LeaveScope (); + + label.EnterScope ("policy-xml"); + if (!hasPolicyXml) + Assert.That (xml, Is.Null, label.Get ()); + else if (context.CheckPolicyXml) { + Assert.That (xml, Is.Not.Null, label.Get ()); + + Assert.That (xml.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ()); + Assert.That (xml.LocalName, Is.EqualTo ("PolicyReference"), label.Get ()); + } + label.LeaveScope (); + + var importer = new WsdlImporter (doc); + + label.EnterScope ("bindings"); + var bindings = importer.ImportAllBindings (); + CheckImportErrors (importer, label); + + Assert.That (bindings, Is.Not.Null, label.Get ()); + Assert.That (bindings.Count, Is.EqualTo (1), label.Get ()); + + string scheme; + if ((security == BasicHttpSecurityMode.Transport) || + (security == BasicHttpSecurityMode.TransportWithMessageCredential)) + scheme = "https"; + else + scheme = "http"; + + CheckBasicHttpBinding ( + bindings [0], scheme, security, encoding, clientCred, + authScheme, label); + label.LeaveScope (); + + label.EnterScope ("endpoints"); + var endpoints = importer.ImportAllEndpoints (); + CheckImportErrors (importer, label); + + Assert.That (endpoints, Is.Not.Null, label.Get ()); + Assert.That (endpoints.Count, Is.EqualTo (1), label.Get ()); + + CheckEndpoint (endpoints [0], MetadataSamples.HttpUri, label); + label.LeaveScope (); + + label.LeaveScope (); + } + + public static void BasicHttpsBinding ( + TestContext context, MetadataSet doc, BasicHttpSecurityMode security, + WSMessageEncoding encoding, HttpClientCredentialType clientCred, + AuthenticationSchemes authScheme, TestLabel label) + { + label.EnterScope ("basicHttpsBinding"); + + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + + Assert.That (sd.Extensions, Is.Not.Null, label.Get ()); + Assert.That (sd.Extensions.Count, Is.EqualTo (1), label.Get ()); + Assert.That (sd.Extensions [0], Is.InstanceOfType (typeof(XmlElement)), label.Get ()); + + label.EnterScope ("extensions"); + var extension = (XmlElement)sd.Extensions [0]; + Assert.That (extension.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ()); + Assert.That (extension.LocalName, Is.EqualTo ("Policy"), label.Get ()); + label.LeaveScope (); + + label.EnterScope ("bindings"); + Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ()); + var binding = sd.Bindings [0]; + Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ()); + Assert.That (binding.Extensions, Is.Not.Null, label.Get ()); + label.LeaveScope (); + + WS.SoapBinding soap = null; + XmlElement xml = null; + + foreach (var ext in binding.Extensions) { + if (ext is WS.SoapBinding) + soap = (WS.SoapBinding)ext; + else if (ext is XmlElement) + xml = (XmlElement)ext; + } + + CheckSoapBinding (soap, WS.SoapBinding.HttpTransport, label); + + if (context.CheckPolicyXml) { + label.EnterScope ("policy-xml"); + Assert.That (xml, Is.Not.Null, label.Get ()); + Assert.That (xml.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ()); + Assert.That (xml.LocalName, Is.EqualTo ("PolicyReference"), label.Get ()); + label.LeaveScope (); + } + + label.LeaveScope (); // wsdl + + var importer = new WsdlImporter (doc); + + label.EnterScope ("bindings"); + var bindings = importer.ImportAllBindings (); + CheckImportErrors (importer, label); + Assert.That (bindings, Is.Not.Null, label.Get ()); + Assert.That (bindings.Count, Is.EqualTo (1), label.Get ()); + + CheckBasicHttpBinding ( + bindings [0], "https", security, encoding, + clientCred, authScheme, label); + label.LeaveScope (); + + label.EnterScope ("endpoints"); + var endpoints = importer.ImportAllEndpoints (); + CheckImportErrors (importer, label); + Assert.That (endpoints, Is.Not.Null, label.Get ()); + Assert.That (endpoints.Count, Is.EqualTo (1), label.Get ()); + + CheckEndpoint (endpoints [0], MetadataSamples.HttpsUri, label); + label.LeaveScope (); + + label.LeaveScope (); + } + + public static void CheckNetTcpBinding ( + Binding binding, SecurityMode security, bool reliableSession, + TransferMode transferMode, TestLabel label) + { + label.EnterScope ("net-tcp"); + if (security == SecurityMode.Message) { + Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ()); + } else { + Assert.That (binding, Is.InstanceOfType (typeof(NetTcpBinding)), label.Get ()); + var netTcp = (NetTcpBinding)binding; + Assert.That (netTcp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap12), label.Get ()); + Assert.That (netTcp.MessageVersion, Is.EqualTo (MessageVersion.Soap12WSAddressing10), label.Get ()); + Assert.That (netTcp.Scheme, Is.EqualTo ("net.tcp"), label.Get ()); + Assert.That (netTcp.TransferMode, Is.EqualTo (transferMode), label.Get ()); + + label.EnterScope ("security"); + Assert.That (netTcp.Security, Is.Not.Null, label.Get ()); + Assert.That (netTcp.Security.Mode, Is.EqualTo (security), label.Get ()); + + Assert.That (netTcp.Security.Transport, Is.Not.Null, label.Get ()); + Assert.That (netTcp.Security.Transport.ProtectionLevel, Is.EqualTo (ProtectionLevel.EncryptAndSign), label.Get ()); + Assert.That (netTcp.Security.Transport.ClientCredentialType, Is.EqualTo (TcpClientCredentialType.Windows), label.Get ()); + label.LeaveScope (); + } + + label.EnterScope ("elements"); + + var elements = binding.CreateBindingElements (); + Assert.That (elements, Is.Not.Null, label.Get ()); + + TcpTransportBindingElement transportElement = null; + TransactionFlowBindingElement transactionFlowElement = null; + BinaryMessageEncodingBindingElement encodingElement = null; + WindowsStreamSecurityBindingElement windowsStreamElement = null; + ReliableSessionBindingElement reliableSessionElement = null; + TransportSecurityBindingElement transportSecurityElement = null; + SslStreamSecurityBindingElement sslStreamElement = null; + SymmetricSecurityBindingElement symmSecurityElement = null; + + foreach (var element in elements) { + if (element is TcpTransportBindingElement) + transportElement = (TcpTransportBindingElement)element; + else if (element is TransactionFlowBindingElement) + transactionFlowElement = (TransactionFlowBindingElement)element; + else if (element is BinaryMessageEncodingBindingElement) + encodingElement = (BinaryMessageEncodingBindingElement)element; + else if (element is WindowsStreamSecurityBindingElement) + windowsStreamElement = (WindowsStreamSecurityBindingElement)element; + else if (element is ReliableSessionBindingElement) + reliableSessionElement = (ReliableSessionBindingElement)element; + else if (element is TransportSecurityBindingElement) + transportSecurityElement = (TransportSecurityBindingElement)element; + else if (element is SslStreamSecurityBindingElement) + sslStreamElement = (SslStreamSecurityBindingElement)element; + else if (element is SymmetricSecurityBindingElement) + symmSecurityElement = (SymmetricSecurityBindingElement)element; + else + Assert.Fail (string.Format ( + "Unknown element `{0}'.", element.GetType ()), label.Get ()); + } + + label.EnterScope ("windows-stream"); + if (security == SecurityMode.Transport) { + Assert.That (windowsStreamElement, Is.Not.Null, label.Get ()); + Assert.That (windowsStreamElement.ProtectionLevel, Is.EqualTo (ProtectionLevel.EncryptAndSign), label.Get ()); + } else { + Assert.That (windowsStreamElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("reliable-session"); + if (reliableSession) { + Assert.That (reliableSessionElement, Is.Not.Null, label.Get ()); + } else { + Assert.That (reliableSessionElement, Is.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("encoding"); + Assert.That (encodingElement, Is.Not.Null, label.Get ()); + label.LeaveScope (); + + label.EnterScope ("transaction"); + if (security == SecurityMode.Message) { + Assert.That (transactionFlowElement, Is.Null, label.Get ()); + } else { + Assert.That (transactionFlowElement, Is.Not.Null, label.Get ()); + } + label.LeaveScope (); + + label.EnterScope ("transport"); + Assert.That (transportElement, Is.Not.Null, label.Get ()); + + Assert.That (transportElement.Scheme, Is.EqualTo ("net.tcp"), label.Get ()); + Assert.That (transportElement.TransferMode, Is.EqualTo (transferMode), label.Get ()); + label.LeaveScope (); // transport + + label.EnterScope ("security"); + switch (security) { + case SecurityMode.None: + case SecurityMode.Transport: + Assert.That (transportSecurityElement, Is.Null, label.Get ()); + Assert.That (sslStreamElement, Is.Null, label.Get ()); + Assert.That (symmSecurityElement, Is.Null, label.Get ()); + break; + case SecurityMode.TransportWithMessageCredential: + Assert.That (transportSecurityElement, Is.Not.Null, label.Get ()); + Assert.That (sslStreamElement, Is.Not.Null, label.Get ()); + Assert.That (symmSecurityElement, Is.Null, label.Get ()); + break; + case SecurityMode.Message: + Assert.That (transportSecurityElement, Is.Null, label.Get ()); + Assert.That (sslStreamElement, Is.Null, label.Get ()); + Assert.That (symmSecurityElement, Is.Not.Null, label.Get ()); + break; + default: + throw new InvalidOperationException (); + } + label.LeaveScope (); + + label.LeaveScope (); // elements + label.LeaveScope (); // net-tcp + } + + public static void NetTcpBinding ( + TestContext context, MetadataSet doc, SecurityMode security, + bool reliableSession, TransferMode transferMode, TestLabel label) + { + label.EnterScope ("netTcpBinding"); + + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + + label.EnterScope ("extensions"); + Assert.That (sd.Extensions, Is.Not.Null, label.Get ()); + Assert.That (sd.Extensions.Count, Is.EqualTo (1), label.Get ()); + Assert.That (sd.Extensions [0], Is.InstanceOfType (typeof(XmlElement)), label.Get ()); + + var extension = (XmlElement)sd.Extensions [0]; + Assert.That (extension.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ()); + Assert.That (extension.LocalName, Is.EqualTo ("Policy"), label.Get ()); + label.LeaveScope (); + + label.EnterScope ("bindings"); + Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ()); + var binding = sd.Bindings [0]; + Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ()); + Assert.That (binding.Extensions, Is.Not.Null, label.Get ()); + + WS.SoapBinding soap = null; + XmlElement xml = null; + + foreach (var ext in binding.Extensions) { + if (ext is WS.SoapBinding) + soap = (WS.SoapBinding)ext; + else if (ext is XmlElement) + xml = (XmlElement)ext; + } + + CheckSoapBinding (soap, "http://schemas.microsoft.com/soap/tcp", label); + + if (context.CheckPolicyXml) { + label.EnterScope ("policy-xml"); + Assert.That (xml, Is.Not.Null, label.Get ()); + + Assert.That (xml.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ()); + Assert.That (xml.LocalName, Is.EqualTo ("PolicyReference"), label.Get ()); + label.LeaveScope (); + } + + label.LeaveScope (); // wsdl + + var importer = new WsdlImporter (doc); + + label.EnterScope ("bindings"); + var bindings = importer.ImportAllBindings (); + CheckImportErrors (importer, label); + Assert.That (bindings, Is.Not.Null, label.Get ()); + Assert.That (bindings.Count, Is.EqualTo (1), label.Get ()); + + CheckNetTcpBinding ( + bindings [0], security, reliableSession, + transferMode, label); + label.LeaveScope (); + + label.EnterScope ("endpoints"); + var endpoints = importer.ImportAllEndpoints (); + CheckImportErrors (importer, label); + Assert.That (endpoints, Is.Not.Null, label.Get ()); + Assert.That (endpoints.Count, Is.EqualTo (1), label.Get ()); + + CheckEndpoint (endpoints [0], MetadataSamples.NetTcpUri, label); + label.LeaveScope (); + + label.LeaveScope (); + } + + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.cs new file mode 100644 index 00000000000..c1138087e62 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.cs @@ -0,0 +1,36 @@ +// +// Main.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public static class ExportUtil { + public static void Main (string[] args) + { + MetadataSamples.Export (); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.csproj b/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.csproj new file mode 100644 index 00000000000..4b304afaa70 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ExportUtil.csproj @@ -0,0 +1,45 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {D4C1B0BD-3488-441C-92B9-7E017041E137} + Exe + ExportUtil + ExportUtil + + + True + full + False + bin\Debug + DEBUG; + prompt + 4 + True + + + none + True + bin\Release + prompt + 4 + True + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests.cs new file mode 100644 index 00000000000..9f167c479cd --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests.cs @@ -0,0 +1,276 @@ +// +// Testcases.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Net; +using System.Xml; +using System.Text; +using System.Collections.Generic; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using NUnit.Framework; +using NUnit.Framework.Constraints; +using NUnit.Framework.SyntaxHelpers; + +using WS = System.Web.Services.Description; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + /* + * This class is abstract to allow it to be run multiple times with + * different TestContexts. + */ + [Category ("MetadataTests")] + public abstract class ImportTests { + + public abstract TestContext Context { + get; + } + + protected MetadataSet GetMetadata (string name, out TestLabel label) + { + label = new TestLabel (name); + return Context.GetMetadata (name); + } + + [Test] + public virtual void BasicHttp () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, BasicHttpSecurityMode.None, label); + } + + [Test] + public virtual void BasicHttp_TransportSecurity () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp_TransportSecurity", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, BasicHttpSecurityMode.Transport, label); + } + + [Test] + [Category ("NotWorking")] + public virtual void BasicHttp_MessageSecurity () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp_MessageSecurity", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, BasicHttpSecurityMode.Message, label); + } + + [Test] + [Category ("NotWorking")] + public virtual void BasicHttp_TransportWithMessageCredential () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp_TransportWithMessageCredential", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, BasicHttpSecurityMode.TransportWithMessageCredential, label); + } + + [Test] + public virtual void BasicHttp_Mtom () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp_Mtom", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, WSMessageEncoding.Mtom, label); + } + + [Test] + public virtual void BasicHttp_NtlmAuth () + { + TestLabel label; + var doc = GetMetadata ("BasicHttp_NtlmAuth", out label); + + BindingTestAssertions.BasicHttpBinding ( + Context, doc, BasicHttpSecurityMode.TransportCredentialOnly, + WSMessageEncoding.Text, HttpClientCredentialType.Ntlm, + AuthenticationSchemes.Ntlm, label); + } + + [Test] + public virtual void BasicHttps () + { + TestLabel label; + var doc = GetMetadata ("BasicHttps", out label); + + BindingTestAssertions.BasicHttpsBinding ( + Context, doc, BasicHttpSecurityMode.Transport, WSMessageEncoding.Text, + HttpClientCredentialType.None, AuthenticationSchemes.Anonymous, + label); + } + + [Test] + public virtual void BasicHttps_NtlmAuth () + { + TestLabel label; + var doc = GetMetadata ("BasicHttps_NtlmAuth", out label); + + BindingTestAssertions.BasicHttpsBinding ( + Context, doc, BasicHttpSecurityMode.Transport, WSMessageEncoding.Text, + HttpClientCredentialType.Ntlm, AuthenticationSchemes.Ntlm, + label); + } + + [Test] + [Category ("NotWorking")] + public virtual void BasicHttps_Certificate () + { + TestLabel label; + var doc = GetMetadata ("BasicHttps_Certificate", out label); + + BindingTestAssertions.BasicHttpsBinding ( + Context, doc, BasicHttpSecurityMode.Transport, WSMessageEncoding.Text, + HttpClientCredentialType.Certificate, AuthenticationSchemes.Anonymous, + label); + } + + [Test] + [Category ("NotWorking")] + public virtual void BasicHttps_TransportWithMessageCredential () + { + TestLabel label; + var doc = GetMetadata ("BasicHttps_TransportWithMessageCredential", out label); + + BindingTestAssertions.BasicHttpsBinding ( + Context, doc, BasicHttpSecurityMode.TransportWithMessageCredential, + WSMessageEncoding.Text, HttpClientCredentialType.None, + AuthenticationSchemes.Anonymous, label); + } + + [Test] + public virtual void NetTcp () + { + TestLabel label; + var doc = GetMetadata ("NetTcp", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.None, false, TransferMode.Buffered, label); + } + + [Test] + public virtual void NetTcp_TransferMode () + { + TestLabel label; + var doc = GetMetadata ("NetTcp_TransferMode", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.None, false, + TransferMode.Streamed, label); + } + + [Test] + public virtual void NetTcp_TransportSecurity () + { + TestLabel label; + var doc = GetMetadata ("NetTcp_TransportSecurity", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.Transport, false, + TransferMode.Buffered, label); + } + + [Test] + [Category ("NotWorking")] + public virtual void NetTcp_MessageSecurity () + { + TestLabel label; + var doc = GetMetadata ("NetTcp_MessageSecurity", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.Message, false, + TransferMode.Buffered, label); + } + + [Test] + [Category ("NotWorking")] + public virtual void NetTcp_TransportWithMessageCredential () + { + TestLabel label; + var doc = GetMetadata ("NetTcp_TransportWithMessageCredential", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.TransportWithMessageCredential, false, + TransferMode.Buffered, label); + } + + [Test] + public virtual void NetTcp_Binding () + { + var label = new TestLabel ("NetTcp_Binding"); + + label.EnterScope ("None"); + BindingTestAssertions.CheckNetTcpBinding ( + new NetTcpBinding (SecurityMode.None), SecurityMode.None, + false, TransferMode.Buffered, label); + label.LeaveScope (); + + label.EnterScope ("Transport"); + BindingTestAssertions.CheckNetTcpBinding ( + new NetTcpBinding (SecurityMode.Transport), SecurityMode.Transport, + false, TransferMode.Buffered, label); + label.LeaveScope (); + } + + [Test] + [Category ("NotWorking")] + public virtual void NetTcp_Binding2 () + { + var label = new TestLabel ("NetTcp_Binding2"); + + label.EnterScope ("TransportWithMessageCredential"); + BindingTestAssertions.CheckNetTcpBinding ( + new NetTcpBinding (SecurityMode.TransportWithMessageCredential), + SecurityMode.TransportWithMessageCredential, false, + TransferMode.Buffered, label); + label.LeaveScope (); + } + + [Test] + [Category ("NotWorking")] + public virtual void NetTcp_ReliableSession () + { + TestLabel label; + var doc = GetMetadata ("NetTcp_ReliableSession", out label); + + BindingTestAssertions.NetTcpBinding ( + Context, doc, SecurityMode.None, true, + TransferMode.Buffered, label); + } + } + +} + diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_CreateMetadata.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_CreateMetadata.cs new file mode 100644 index 00000000000..ff1a0ff89fc --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_CreateMetadata.cs @@ -0,0 +1,91 @@ +// +// ImportTests_CreateMetadata.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + /* + * Create the metadata programmatically. + * + */ + [TestFixture] + public class ImportTests_CreateMetadata : ImportTests { + + public override TestContext Context { + get { return TestContext.CreateMetadataContext; } + } + + [Category ("NotWorking")] + public override void BasicHttp_Mtom () + { + base.BasicHttp_Mtom (); + } + + [Category ("NotWorking")] + public override void BasicHttp_NtlmAuth () + { + base.BasicHttp_NtlmAuth (); + } + + [Category ("NotWorking")] + public override void BasicHttp_TransportSecurity () + { + base.BasicHttp_TransportSecurity (); + } + + [Category ("NotWorking")] + public override void BasicHttps () + { + base.BasicHttps (); + } + + [Category ("NotWorking")] + public override void BasicHttps_NtlmAuth () + { + base.BasicHttps_NtlmAuth (); + } + + [Category ("NotWorking")] + public override void NetTcp () + { + base.NetTcp_Binding (); + } + + [Category ("NotWorking")] + public override void NetTcp_TransferMode () + { + base.NetTcp_TransferMode (); + } + + [Category ("NotWorking")] + public override void NetTcp_TransportSecurity () + { + base.NetTcp_TransportSecurity (); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_LoadMetadata.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_LoadMetadata.cs new file mode 100644 index 00000000000..1426bcacb07 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_LoadMetadata.cs @@ -0,0 +1,44 @@ +// +// ImportTests_LoadMetadata.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + /* + * Load the metadata from a file / embedded resource. + * + */ + [TestFixture] + public class ImportTests_LoadMetadata : ImportTests { + + public override TestContext Context { + get { return TestContext.LoadMetadataContext; } + } + + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_RoundTrip.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_RoundTrip.cs new file mode 100644 index 00000000000..bf4f3af1c68 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/ImportTests_RoundTrip.cs @@ -0,0 +1,95 @@ +// +// ImportTests_RoundTrip.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + /* + * Export the metadata into a string, then import it back. + * + * This tests both the WsdlExporter and the WsdlImporter. + * + */ + [TestFixture] + //[Category ("NotWorking")] + public class ImportTests_RoundTrip : ImportTests { + + public override TestContext Context { + get { return TestContext.RoundTripContext; } + } + + [Category ("NotWorking")] + public override void BasicHttp_Mtom () + { + base.BasicHttp_Mtom (); + } + + [Category ("NotWorking")] + public override void BasicHttp_NtlmAuth () + { + base.BasicHttp_NtlmAuth (); + } + + [Category ("NotWorking")] + public override void BasicHttp_TransportSecurity () + { + base.BasicHttp_TransportSecurity (); + } + + [Category ("NotWorking")] + public override void BasicHttps () + { + base.BasicHttps (); + } + + [Category ("NotWorking")] + public override void BasicHttps_NtlmAuth () + { + base.BasicHttps_NtlmAuth (); + } + + [Category ("NotWorking")] + public override void NetTcp () + { + base.NetTcp_Binding (); + } + + [Category ("NotWorking")] + public override void NetTcp_TransferMode () + { + base.NetTcp_TransferMode (); + } + + [Category ("NotWorking")] + public override void NetTcp_TransportSecurity () + { + base.NetTcp_TransportSecurity (); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataSamples.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataSamples.cs new file mode 100644 index 00000000000..d170578fc51 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataSamples.cs @@ -0,0 +1,372 @@ +// +// MetadataProvider.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.IO; +using System.Reflection; +using System.ServiceModel; +using System.ServiceModel.Security; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Configuration; +using WS = System.Web.Services.Description; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public static class MetadataSamples { + + internal const string HttpUri = "http://tempuri.org/TestHttp/"; + internal const string HttpsUri = "https://tempuri.org/TestHttps/"; + internal const string NetTcpUri = "net-tcp://tempuri.org:8000/TestNetTcp/"; + internal const string CustomUri = "custom://tempuri.org:8000/Test/"; + + [MetadataSample] + public static MetadataSet BasicHttp () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new BasicHttpBinding (), new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttp_TransportSecurity () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpBinding (); + binding.Security.Mode = BasicHttpSecurityMode.Transport; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttp_MessageSecurity () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpBinding (); + binding.Security.Mode = BasicHttpSecurityMode.Message; + binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttp_TransportWithMessageCredential () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpBinding (); + binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttp_Mtom () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpBinding (); + binding.MessageEncoding = WSMessageEncoding.Mtom; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttp_NtlmAuth () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpBinding (BasicHttpSecurityMode.TransportCredentialOnly); + binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + +#if NET_4_5 + [MetadataSample] + public static MetadataSet BasicHttps () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new BasicHttpsBinding (), new EndpointAddress (HttpsUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttps_NtlmAuth () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpsBinding (); + + binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpsUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttps_Certificate () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpsBinding (); + binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpsUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet BasicHttps_TransportWithMessageCredential () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new BasicHttpsBinding (BasicHttpsSecurityMode.TransportWithMessageCredential); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (HttpsUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } +#endif + + [MetadataSample] + public static MetadataSet NetTcp () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new NetTcpBinding (SecurityMode.None, false), + new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet NetTcp_TransportSecurity () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new NetTcpBinding (SecurityMode.Transport, false), + new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet NetTcp_MessageSecurity () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new NetTcpBinding (SecurityMode.Message, false), + new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet NetTcp_TransportWithMessageCredential () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, new NetTcpBinding (SecurityMode.TransportWithMessageCredential, false), + new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet NetTcp_ReliableSession () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new NetTcpBinding (SecurityMode.None, true); + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + [MetadataSample] + public static MetadataSet NetTcp_TransferMode () + { + var exporter = new WsdlExporter (); + + var cd = new ContractDescription ("MyContract"); + + var binding = new NetTcpBinding (SecurityMode.None, false); + binding.TransferMode = TransferMode.Streamed; + + exporter.ExportEndpoint (new ServiceEndpoint ( + cd, binding, new EndpointAddress (NetTcpUri))); + + var doc = exporter.GetGeneratedMetadata (); + return doc; + } + + public static void Export () + { + var bf = BindingFlags.Public | BindingFlags.Static; + foreach (var method in typeof (MetadataSamples).GetMethods (bf)) { + MetadataSampleAttribute sampleAttr = null; + foreach (var obj in method.GetCustomAttributes (false)) { + var cattr = obj as MetadataSampleAttribute; + if (cattr != null) { + sampleAttr = cattr; + break; + } + } + + if (sampleAttr == null) + continue; + + var name = sampleAttr.Name ?? method.Name; + var doc = (MetadataSet)method.Invoke (null, null); + TestContext.SaveMetadata (name, doc); + } + } + + public static MetadataSet GetMetadataByName (string name) + { + if (name.EndsWith (".xml")) + name = name.Substring (name.Length - 4); + + var bf = BindingFlags.Public | BindingFlags.Static; + foreach (var method in typeof (MetadataSamples).GetMethods (bf)) { + MetadataSampleAttribute sampleAttr = null; + foreach (var obj in method.GetCustomAttributes (false)) { + var cattr = obj as MetadataSampleAttribute; + if (cattr != null) { + sampleAttr = cattr; + break; + } + } + + if (sampleAttr == null) + continue; + + if (!name.Equals (sampleAttr.Name ?? method.Name)) + continue; + + return (MetadataSet)method.Invoke (null, null); + } + + throw new InvalidOperationException (); + } + + public class MetadataSampleAttribute : Attribute { + + public MetadataSampleAttribute () + { + } + + public MetadataSampleAttribute (string name) + { + Name = name; + } + + public string Name { + get; set; + } + + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.csproj b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.csproj new file mode 100644 index 00000000000..1058beb9ca1 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.csproj @@ -0,0 +1,79 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {7731D464-5152-4A1B-AACB-6B5A7CA9ACAA} + Library + MetadataTests + MetadataTests + v4.5 + + + True + full + False + bin\Debug + DEBUG;USE_EMBEDDED_METADATA;NET_4_5 + prompt + 4 + False + + + none + True + bin\Release + prompt + 4 + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.sln b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.sln new file mode 100644 index 00000000000..30861792ceb --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/MetadataTests.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetadataTests", "MetadataTests.csproj", "{7731D464-5152-4A1B-AACB-6B5A7CA9ACAA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportUtil", "ExportUtil.csproj", "{D4C1B0BD-3488-441C-92B9-7E017041E137}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7731D464-5152-4A1B-AACB-6B5A7CA9ACAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7731D464-5152-4A1B-AACB-6B5A7CA9ACAA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7731D464-5152-4A1B-AACB-6B5A7CA9ACAA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7731D464-5152-4A1B-AACB-6B5A7CA9ACAA}.Release|Any CPU.Build.0 = Release|Any CPU + {D4C1B0BD-3488-441C-92B9-7E017041E137}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4C1B0BD-3488-441C-92B9-7E017041E137}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4C1B0BD-3488-441C-92B9-7E017041E137}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4C1B0BD-3488-441C-92B9-7E017041E137}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = MetadataTests.csproj + EndGlobalSection +EndGlobal diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/MiscImportTests.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/MiscImportTests.cs new file mode 100644 index 00000000000..f6656e5c7d9 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/MiscImportTests.cs @@ -0,0 +1,281 @@ +// +// Test_Misc.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Net; +using System.Xml; +using System.Text; +using System.Collections.Generic; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using NUnit.Framework; +using NUnit.Framework.Constraints; +using NUnit.Framework.SyntaxHelpers; + +using WS = System.Web.Services.Description; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public class MiscImportTests { + + [Test] + public void BasicHttpBinding_ImportBinding () + { + var label = new TestLabel ("BasicHttpBinding_ImportBinding"); + + var doc = TestContext.LoadMetadata ("BasicHttp"); + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + var wsdlBinding = sd.Bindings [0]; + + var importer = new WsdlImporter (doc); + + Assert.That (sd.Bindings, Is.Not.Null, label.Get ()); + Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ()); + + var binding = importer.ImportBinding (wsdlBinding); + BindingTestAssertions.CheckImportErrors (importer, label); + Assert.That (binding, Is.Not.Null, label.Get ()); + } + + [Test] + public void BasicHttpBinding_ImportEndpoint () + { + var label = new TestLabel ("BasicHttpBinding_ImportEndpoint"); + + var doc = TestContext.LoadMetadata ("BasicHttp"); + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + Assert.That (sd.Services, Is.Not.Null, label.Get ()); + Assert.That (sd.Services.Count, Is.EqualTo (1), label.Get ()); + + var service = sd.Services [0]; + Assert.That (service.Ports, Is.Not.Null, label.Get ()); + Assert.That (service.Ports.Count, Is.EqualTo (1), label.Get ()); + label.LeaveScope (); + + var importer = new WsdlImporter (doc); + + var port = importer.ImportEndpoint (service.Ports [0]); + BindingTestAssertions.CheckImportErrors (importer, label); + Assert.That (port, Is.Not.Null, label.Get ()); + } + + [Test] + public void BasicHttpBinding_Error () + { + var label = new TestLabel ("BasicHttpBinding_Error"); + + var doc = TestContext.LoadMetadata ("http-error.xml"); + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + var wsdlBinding = sd.Bindings [0]; + + var importer = new WsdlImporter (doc); + + label.EnterScope ("all"); + + var bindings = importer.ImportAllBindings (); + Assert.That (bindings, Is.Not.Null, label.Get ()); + Assert.That (bindings.Count, Is.EqualTo (0), label.Get ()); + + label.EnterScope ("errors"); + Assert.That (importer.Errors, Is.Not.Null, label.Get ()); + Assert.That (importer.Errors.Count, Is.EqualTo (1), label.Get ()); + + var error = importer.Errors [0]; + Assert.That (error.IsWarning, Is.False, label.Get ()); + label.LeaveScope (); + label.LeaveScope (); + + label.EnterScope ("single"); + + try { + importer.ImportBinding (wsdlBinding); + Assert.Fail (label.Get ()); + } catch { + ; + } + + Assert.That (importer.Errors.Count, Is.EqualTo (1), label.Get ()); + + label.LeaveScope (); + + label.EnterScope ("single-first"); + + var importer2 = new WsdlImporter (doc); + + try { + importer2.ImportBinding (wsdlBinding); + Assert.Fail (label.Get ()); + } catch { + ; + } + + Assert.That (importer2.Errors.Count, Is.EqualTo (1), label.Get ()); + + try { + importer2.ImportBinding (wsdlBinding); + Assert.Fail (label.Get ()); + } catch { + ; + } + + var bindings2 = importer.ImportAllBindings (); + Assert.That (bindings2, Is.Not.Null, label.Get ()); + Assert.That (bindings2.Count, Is.EqualTo (0), label.Get ()); + + label.LeaveScope (); + } + + [Test] + public void BasicHttpBinding_Error2 () + { + var label = new TestLabel ("BasicHttpBinding_Error2"); + + var doc = TestContext.LoadMetadata ("http-error.xml"); + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + Assert.That (sd.Services, Is.Not.Null, label.Get ()); + Assert.That (sd.Services.Count, Is.EqualTo (1), label.Get ()); + + var service = sd.Services [0]; + Assert.That (service.Ports, Is.Not.Null, label.Get ()); + Assert.That (service.Ports.Count, Is.EqualTo (1), label.Get ()); + label.LeaveScope (); + + var importer = new WsdlImporter (doc); + + label.EnterScope ("all"); + + var endpoints = importer.ImportAllEndpoints (); + Assert.That (endpoints, Is.Not.Null, label.Get ()); + Assert.That (endpoints.Count, Is.EqualTo (0), label.Get ()); + + label.EnterScope ("errors"); + Assert.That (importer.Errors, Is.Not.Null, label.Get ()); + Assert.That (importer.Errors.Count, Is.EqualTo (2), label.Get ()); + + Assert.That (importer.Errors [0].IsWarning, Is.False, label.Get ()); + Assert.That (importer.Errors [1].IsWarning, Is.False, label.Get ()); + label.LeaveScope (); + label.LeaveScope (); + + label.EnterScope ("single"); + + try { + importer.ImportEndpoint (service.Ports [0]); + Assert.Fail (label.Get ()); + } catch { + ; + } + + Assert.That (importer.Errors.Count, Is.EqualTo (2), label.Get ()); + + label.LeaveScope (); + + label.EnterScope ("single-first"); + + var importer2 = new WsdlImporter (doc); + + try { + importer2.ImportEndpoint (service.Ports [0]); + Assert.Fail (label.Get ()); + } catch { + ; + } + + Assert.That (importer2.Errors.Count, Is.EqualTo (2), label.Get ()); + + try { + importer2.ImportEndpoint (service.Ports [0]); + Assert.Fail (label.Get ()); + } catch { + ; + } + + var endpoints2 = importer.ImportAllEndpoints (); + Assert.That (endpoints2, Is.Not.Null, label.Get ()); + Assert.That (endpoints2.Count, Is.EqualTo (0), label.Get ()); + + label.LeaveScope (); + } + + [Test] + public void BasicHttpBinding_ImportEndpoints () + { + var label = new TestLabel ("BasicHttpBinding_ImportEndpoints"); + + var doc = TestContext.LoadMetadata ("BasicHttp"); + var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata; + + label.EnterScope ("wsdl"); + Assert.That (sd.Bindings, Is.Not.Null, label.Get ()); + Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ()); + var binding = sd.Bindings [0]; + + Assert.That (sd.Services, Is.Not.Null, label.Get ()); + Assert.That (sd.Services.Count, Is.EqualTo (1), label.Get ()); + var service = sd.Services [0]; + + Assert.That (service.Ports, Is.Not.Null, label.Get ()); + Assert.That (service.Ports.Count, Is.EqualTo (1), label.Get ()); + var port = service.Ports [0]; + + Assert.That (sd.PortTypes, Is.Not.Null, label.Get ()); + Assert.That (sd.PortTypes.Count, Is.EqualTo (1), label.Get ()); + var portType = sd.PortTypes [0]; + + label.LeaveScope (); + + var importer = new WsdlImporter (doc); + + label.EnterScope ("by-service"); + var byService = importer.ImportEndpoints (service); + BindingTestAssertions.CheckImportErrors (importer, label); + Assert.That (byService, Is.Not.Null, label.Get ()); + Assert.That (byService.Count, Is.EqualTo (1), label.Get ()); + label.LeaveScope (); + + label.EnterScope ("by-binding"); + var byBinding = importer.ImportEndpoints (binding); + BindingTestAssertions.CheckImportErrors (importer, label); + Assert.That (byBinding, Is.Not.Null, label.Get ()); + Assert.That (byBinding.Count, Is.EqualTo (1), label.Get ()); + label.LeaveScope (); + + label.EnterScope ("by-port-type"); + var byPortType = importer.ImportEndpoints (portType); + BindingTestAssertions.CheckImportErrors (importer, label); + Assert.That (byPortType, Is.Not.Null, label.Get ()); + Assert.That (byPortType.Count, Is.EqualTo (1), label.Get ()); + label.LeaveScope (); + } + + } +} + diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/README.txt b/mcs/class/System.ServiceModel/Test/MetadataTests/README.txt new file mode 100644 index 00000000000..a1ed18eaa35 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/README.txt @@ -0,0 +1,54 @@ +Metadata Tests +============== + +These tests can be run either as part of System.ServiceModel_test_.dll +or as the stand-alone MetadataTests.dll, which bundles all the XML files as +embedded resources. + +Generating and updating the XML Samples: +======================================== + +Mono's WsdlExporter is not yet capable of generating the wsdl files that +are used as test input here. + +To generate the XML files, compile the ExportUtil.exe tool either by using the +ExportUtil.csproj or compiling it manually: + + mcs -r:System.ServiceModel -r:System.Web.Services ExportUtil.cs MetadataSamples.cs TestContext.cs + +Then copy the binary to a Windows machine and run it there. This will generate a bunch of +.xml files. Run dos2unix on them and copy them into the Resources/ subdirectory. + +Adding new Tests: +================= + +To add a new test, add a method with the [MetadataaSample] attribute to +MetadataSamples.cs, like this: + + [MetadataSample] + public static MetadataSet MyXML () + { + .... + } + +You may also specify a name: + + [MetadataSample ("MyXML")] + public static MetadataSet RandomMethodName () + { + } + +Re-compile ExportUtil.exe and it will produce a new 'MyXML.xml' file. + +Then write a new test case: + + [Test] + public void MyXML () + { + var doc = TestContext.GetMetadata ("MyXML"); + ... test it here + } + +The idea behind the 'TestContext' class is to allow "self-hosting" at a +later time, ie. use Mono's WsdlExporter to generate the metadata instead +of loading the on-disk file without having to modify a bunch of tests. diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp.xml new file mode 100644 index 00000000000..82ce03c0191 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_MessageSecurity.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_MessageSecurity.xml new file mode 100644 index 00000000000..7a442fff979 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_MessageSecurity.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_Mtom.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_Mtom.xml new file mode 100644 index 00000000000..9e827c0d707 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_Mtom.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_NtlmAuth.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_NtlmAuth.xml new file mode 100644 index 00000000000..e8650187558 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_NtlmAuth.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportSecurity.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportSecurity.xml new file mode 100644 index 00000000000..82ab01bfe98 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportSecurity.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportWithMessageCredential.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportWithMessageCredential.xml new file mode 100644 index 00000000000..09055425504 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttp_TransportWithMessageCredential.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps.xml new file mode 100644 index 00000000000..9ed00e4a2b6 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_Certificate.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_Certificate.xml new file mode 100644 index 00000000000..f8b19ccd398 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_Certificate.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_NtlmAuth.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_NtlmAuth.xml new file mode 100644 index 00000000000..ad6772e1dee --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_NtlmAuth.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_TransportWithMessageCredential.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_TransportWithMessageCredential.xml new file mode 100644 index 00000000000..f688906a19b --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/BasicHttps_TransportWithMessageCredential.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp.xml new file mode 100644 index 00000000000..7edf87acf14 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_MessageSecurity.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_MessageSecurity.xml new file mode 100644 index 00000000000..59534645991 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_MessageSecurity.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_ReliableSession.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_ReliableSession.xml new file mode 100644 index 00000000000..85d1bd0f432 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_ReliableSession.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransferMode.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransferMode.xml new file mode 100644 index 00000000000..f8c5e4501d3 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransferMode.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportSecurity.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportSecurity.xml new file mode 100644 index 00000000000..3ba464aed69 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportSecurity.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + EncryptAndSign + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportWithMessageCredential.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportWithMessageCredential.xml new file mode 100644 index 00000000000..9d26993bc31 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/NetTcp_TransportWithMessageCredential.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + net-tcp://tempuri.org:8000/TestNetTcp/ + + + + + + \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/http-error.xml b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/http-error.xml new file mode 100644 index 00000000000..d8678d5fbb4 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/Resources/http-error.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/TestContext.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/TestContext.cs new file mode 100644 index 00000000000..e1dfc6ec8b3 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/TestContext.cs @@ -0,0 +1,206 @@ +// +// ITestContext.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.IO; +using System.Xml; +using System.Text; +using System.Reflection; +using System.ServiceModel.Description; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public abstract class TestContext { + + #region Abstract API + + public abstract MetadataSet GetMetadata (string name); + + /* + * Whether or not to check whether the `WS.Binding.Extensions' + * contains the policy XmlElement. + * + * We only check when importing from XML, not when generating + * the MetadataSet programmatically. + */ + public abstract bool CheckPolicyXml { + get; + } + + #endregion + + #region Default Context + + public static TestContext LoadMetadataContext = new _LoadMetadataContext (); + + public static TestContext CreateMetadataContext = new _CreateMetadataContext (); + + public static TestContext RoundTripContext = new _RoundTripContext (); + + #endregion + + #region Implementations + + class _LoadMetadataContext : TestContext { + public override MetadataSet GetMetadata (string name) + { + return LoadMetadata (name); + } + + public override bool CheckPolicyXml { + get { + return true; + } + } + } + + class _CreateMetadataContext : TestContext { + public override MetadataSet GetMetadata (string name) + { + return MetadataSamples.GetMetadataByName (name); + } + + public override bool CheckPolicyXml { + get { + // FIXME: Not supported yet. + return false; + } + } + } + + class _RoundTripContext : TestContext { + public override MetadataSet GetMetadata (string name) + { + return RoundTrip (name); + } + + public override bool CheckPolicyXml { + get { + // FIXME: Not supported yet. + return false; + } + } + } + + #endregion + + #region Public Static API + + public static MetadataSet LoadMetadata (string name) + { +#if USE_EMBEDDED_METADATA + return LoadMetadataFromResource (name); +#else + return LoadMetadataFromFile (name); +#endif + } + + public static void SaveMetadata (string name, MetadataSet metadata) + { + SaveMetadataToFile (name, metadata); + } + + public static MetadataSet LoadMetadataFromFile (string name) + { + var asm = Assembly.GetExecutingAssembly (); + if (!name.EndsWith (".xml")) + name = name + ".xml"; + var uri = new Uri (asm.CodeBase); + var path = Path.GetDirectoryName (uri.AbsolutePath); + path = Path.Combine (path, "Test"); + path = Path.Combine (path, "MetadataTests"); + path = Path.Combine (path, "Resources"); + var filename = Path.Combine (path, name); + using (var stream = new StreamReader (filename)) { + var reader = new XmlTextReader (stream); + return MetadataSet.ReadFrom (reader); + } + } + + public static MetadataSet LoadMetadataFromResource (string name) + { + var asm = Assembly.GetExecutingAssembly (); + if (!name.EndsWith (".xml")) + name = name + ".xml"; + + var resname = "MetadataTests.Resources." + name; + using (var stream = asm.GetManifestResourceStream (resname)) { + if (stream == null) + throw new InvalidOperationException ( + "No such resource: " + name); + var reader = new XmlTextReader (stream); + return MetadataSet.ReadFrom (reader); + } + } + + public static void SaveMetadataToFile (string name, MetadataSet metadata) + { + var filename = name + ".xml"; + if (File.Exists (filename)) + return; + + using (var file = new StreamWriter (filename, false)) { + var writer = new XmlTextWriter (file); + writer.Formatting = Formatting.Indented; + metadata.WriteTo (writer); + } + + Console.WriteLine ("Exported {0}.", filename); + } + + internal static string SaveMetadataToString (MetadataSet metadata) + { + using (var ms = new MemoryStream ()) { + var writer = new XmlTextWriter (new StreamWriter (ms)); + writer.Formatting = Formatting.Indented; + metadata.WriteTo (writer); + writer.Flush (); + + return Encoding.UTF8.GetString (ms.GetBuffer (), 0, (int)ms.Position); + } + } + + internal static MetadataSet LoadMetadataFromString (string doc) + { + var buffer = Encoding.UTF8.GetBytes (doc); + using (var ms = new MemoryStream (buffer)) { + var reader = new XmlTextReader (ms); + return MetadataSet.ReadFrom (reader); + } + } + + public static MetadataSet RoundTrip (string name) + { + var metadata = MetadataSamples.GetMetadataByName (name); + + var doc = SaveMetadataToString (metadata); + return LoadMetadataFromString (doc); + } + + #endregion + } +} + diff --git a/mcs/class/System.ServiceModel/Test/MetadataTests/TestLabel.cs b/mcs/class/System.ServiceModel/Test/MetadataTests/TestLabel.cs new file mode 100644 index 00000000000..76bd1ff930f --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/MetadataTests/TestLabel.cs @@ -0,0 +1,138 @@ +// +// TestLabel.cs +// +// Author: +// Martin Baulig +// +// Copyright (c) 2012 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 "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Text; +using System.Collections.Generic; + +namespace MonoTests.System.ServiceModel.MetadataTests { + + public class TestLabel { + + List scopes; + string delimiter; + Style defaultStyle; + + public enum Style { + Letter, + Number, + HexNumer + } + + public TestLabel (string prefix) + : this (prefix, ".", Style.Letter) + { + } + + public TestLabel (string prefix, string delimiter, Style style) + { + if ((prefix == null) || (prefix.Equals (string.Empty))) + throw new ArgumentException ("Cannot be null or empty.", "prefix"); + if (delimiter == null) + throw new ArgumentNullException ("delimiter"); + + scopes = new List (); + scopes.Add (new Scope (prefix, style)); + + this.delimiter = delimiter; + this.defaultStyle = style; + } + + class Scope { + public readonly string Text; + public readonly Style Style; + int id; + + public Scope (string text, Style style) + { + this.Text = text; + this.Style = style; + this.id = 0; + } + + public int GetID () + { + return ++id; + } + } + + public void EnterScope (string scope) + { + scopes.Add (new Scope (scope, defaultStyle)); + } + + public void LeaveScope () + { + if (scopes.Count <= 1) + throw new InvalidOperationException (); + scopes.RemoveAt (scopes.Count - 1); + } + + public string Get () + { + var sb = new StringBuilder (); + for (int i = 0; i < scopes.Count; i++) { + sb.Append (scopes [i].Text); + sb.Append (delimiter); + } + + var scope = scopes [scopes.Count - 1]; + var id = scope.GetID (); + + switch (scope.Style) { + case Style.Letter: + if (id <= 26) + sb.Append ((char)('a' + id - 1)); + else + goto case Style.Number; + break; + + case Style.Number: + sb.Append (id); + break; + + case Style.HexNumer: + sb.AppendFormat ("{0:x2}", id); + break; + } + + return sb.ToString (); + } + + public override string ToString () + { + var sb = new StringBuilder (); + sb.Append ("["); + for (int i = 0; i < scopes.Count; i++) { + if (i > 0) + sb.Append (delimiter); + sb.Append (scopes [i].Text); + } + sb.Append ("]"); + return sb.ToString (); + } + } +} + diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlImporterTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlImporterTest.cs index 24630a28263..cf2289e4d7d 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlImporterTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlImporterTest.cs @@ -236,26 +236,6 @@ namespace MonoTests.System.ServiceModel.Description Assert.AreEqual (name, ((XmlElement) o).Name); } - [Test] - public void BindingsTest () - { - NoExtensionsSetup (); - IEnumerable bindings = wi.ImportAllBindings (); - - int count = 0; - foreach (SMBinding b in bindings) { - Assert.AreEqual (typeof (CustomBinding), b.GetType (), "#B1"); - Assert.AreEqual ("BasicHttpBinding_IEchoService", b.Name, "#B2"); - Assert.AreEqual ("http://tempuri.org/", b.Namespace, "#B3"); - Assert.AreEqual ("", b.Scheme, "#B4"); - - //FIXME: Test BindingElements - - count++; - } - Assert.AreEqual (1, count); - } - [Test] [Category ("NotWorking")] public void ContractsTest () @@ -586,7 +566,7 @@ namespace MonoTests.System.ServiceModel.Description var mset = new MetadataSet (); WSServiceDescription sd = null; - sd = WSServiceDescription.Read (XmlReader.Create ("670945.wsdl")); + sd = WSServiceDescription.Read (XmlReader.Create ("Test/XmlFiles/670945.wsdl")); mset.MetadataSections.Add (new MetadataSection () { Dialect = MetadataSection.ServiceDescriptionDialect, Metadata = sd }); diff --git a/mcs/class/System.ServiceModel/net_4_5_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/net_4_5_System.ServiceModel.dll.sources index 374ee6b4279..700c289f474 100644 --- a/mcs/class/System.ServiceModel/net_4_5_System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/net_4_5_System.ServiceModel.dll.sources @@ -1 +1,10 @@ #include net_4_0_System.ServiceModel.dll.sources +System.ServiceModel/HttpBindingBase.cs +System.ServiceModel/BasicHttpBinding_4_5.cs +System.ServiceModel/BasicHttpsBinding.cs +System.ServiceModel/BasicHttpsSecurity.cs +System.ServiceModel.Configuration/BasicHttpBindingElement_4_5.cs +System.ServiceModel.Configuration/HttpBindingBaseElement.cs +System.ServiceModel.Configuration/BasicHttpsBindingElement.cs +System.ServiceModel.Configuration/BasicHttpsSecurityElement.cs +System.ServiceModel.Configuration/BasicHttpsBindingCollectionElement.cs diff --git a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs index 9f693753f55..46bef52a7b4 100644 --- a/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs +++ b/mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JsonDeserializer.cs @@ -2,9 +2,10 @@ // JsonDeserializer.cs // // Author: -// Marek Habersack +// Marek Habersack // // (C) 2008 Novell, Inc. http://novell.com/ +// Copyright 2011, Xamarin, Inc (http://xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -26,34 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Code is based on JSON_checker (http://www.json.org/JSON_checker/) and JSON_parser -// (http://fara.cs.uni-potsdam.de/~jsg/json_parser/) C sources. License for the original code -// follows: - -#region Original License -/* -Copyright (c) 2005 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#endregion +// (http://fara.cs.uni-potsdam.de/~jsg/json_parser/) C sources. using System; using System.Collections; diff --git a/mcs/class/System.Web.Routing/System.Web.Routing/HttpMethodConstraint.cs b/mcs/class/System.Web.Routing/System.Web.Routing/HttpMethodConstraint.cs index f12ec329484..b8e4d604ed2 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing/HttpMethodConstraint.cs +++ b/mcs/class/System.Web.Routing/System.Web.Routing/HttpMethodConstraint.cs @@ -68,12 +68,24 @@ namespace System.Web.Routing if (values == null) throw new ArgumentNullException ("values"); - foreach (string allowed in AllowedMethods) + switch (routeDirection) { + case RouteDirection.IncomingRequest: // LAMESPEC: .NET allows case-insensitive comparison, which violates RFC 2616 - if (httpContext.Request.HttpMethod == allowed) + return AllowedMethods.Contains (httpContext.Request.HttpMethod); + + case RouteDirection.UrlGeneration: + // See: aspnetwebstack's WebAPI equivalent for details. + object method; + + if (!values.TryGetValue (parameterName, out method)) return true; - return false; + // LAMESPEC: .NET allows case-insensitive comparison, which violates RFC 2616 + return AllowedMethods.Contains (Convert.ToString (method)); + + default: + throw new ArgumentException ("Invalid routeDirection: " + routeDirection); + } } } } diff --git a/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs b/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs index 4571bc754a8..aacc322bf34 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs +++ b/mcs/class/System.Web.Routing/System.Web.Routing/PatternParser.cs @@ -352,6 +352,10 @@ namespace System.Web.Routing if (tokens.Count != 1) return null; + // if token is catch-all, we're done. + if (tokens [0].Type == PatternTokenType.CatchAll) + break; + if (!defaults.ContainsKey (tokens [0].Name)) return null; } @@ -361,11 +365,12 @@ namespace System.Web.Routing return AddDefaults (ret, defaults); } - public bool BuildUrl (Route route, RequestContext requestContext, RouteValueDictionary userValues, out string value) + public string BuildUrl (Route route, RequestContext requestContext, RouteValueDictionary userValues, RouteValueDictionary constraints, out RouteValueDictionary usedValues) { - value = null; + usedValues = null; + if (requestContext == null) - return false; + return null; RouteData routeData = requestContext.RouteData; RouteValueDictionary defaultValues = route != null ? route.Defaults : null; @@ -407,10 +412,10 @@ namespace System.Web.Routing // Has the user provided value for it? if (userValues == null || !userValues.ContainsKey (parameterName)) { if (allMustBeInUserValues) - return false; // partial override => no match + return null; // partial override => no match if (!canTakeFromAmbient || ambientValues == null || !ambientValues.ContainsKey (parameterName)) - return false; // no value provided => no match + return null; // no value provided => no match } else if (canTakeFromAmbient) allMustBeInUserValues = true; } @@ -431,28 +436,16 @@ namespace System.Web.Routing object defaultValue = de.Value; if (defaultValue is string && parameterValue is string) { if (String.Compare ((string)defaultValue, (string)parameterValue, StringComparison.Ordinal) != 0) - return false; // different value => no match + return null; // different value => no match } else if (defaultValue != parameterValue) - return false; // different value => no match + return null; // different value => no match } } } - // Check the constraints - RouteValueDictionary constraints = route != null ? route.Constraints : null; - if (constraints != null && constraints.Count > 0) { - HttpContextBase context = requestContext.HttpContext; - bool invalidConstraint; - - foreach (var de in constraints) { - if (!Route.ProcessConstraintInternal (context, route, de.Value, de.Key, userValues, RouteDirection.UrlGeneration, requestContext, out invalidConstraint) || - invalidConstraint) - return false; // constraint not met => no match - } - } - // We're a match, generate the URL var ret = new StringBuilder (); + usedValues = new RouteValueDictionary (); bool canTrim = true; // Going in reverse order, so that we can trim without much ado @@ -475,6 +468,9 @@ namespace System.Web.Routing #if SYSTEMCORE_DEP if (userValues.GetValue (parameterName, out tokenValue)) { + if (tokenValue != null) + usedValues.Add (parameterName, tokenValue.ToString ()); + if (!defaultValues.Has (parameterName, tokenValue)) { canTrim = false; if (tokenValue != null) @@ -484,6 +480,7 @@ namespace System.Web.Routing if (!canTrim && tokenValue != null) ret.Insert (0, tokenValue.ToString ()); + continue; } @@ -491,16 +488,21 @@ namespace System.Web.Routing object ambientTokenValue; if (ambientValues.GetValue (parameterName, out ambientTokenValue)) tokenValue = ambientTokenValue; - + if (!canTrim && tokenValue != null) ret.Insert (0, tokenValue.ToString ()); + + usedValues.Add (parameterName, tokenValue.ToString ()); continue; } canTrim = false; if (ambientValues.GetValue (parameterName, out tokenValue)) { if (tokenValue != null) + { ret.Insert (0, tokenValue.ToString ()); + usedValues.Add (parameterName, tokenValue.ToString ()); + } continue; } #endif @@ -538,11 +540,12 @@ namespace System.Web.Routing ret.Append ('='); if (parameterValue != null) ret.Append (Uri.EscapeDataString (de.Value.ToString ())); + + usedValues.Add (parameterName, de.Value.ToString ()); } } - value = ret.ToString (); - return true; + return ret.ToString (); } } } diff --git a/mcs/class/System.Web.Routing/System.Web.Routing/Route.cs b/mcs/class/System.Web.Routing/System.Web.Routing/Route.cs index 1a7ce99e833..32b0ba9705a 100644 --- a/mcs/class/System.Web.Routing/System.Web.Routing/Route.cs +++ b/mcs/class/System.Web.Routing/System.Web.Routing/Route.cs @@ -102,11 +102,8 @@ namespace System.Web.Routing if (values == null) return null; - RouteValueDictionary constraints = Constraints; - if (constraints != null) - foreach (var p in constraints) - if (!ProcessConstraint (httpContext, p.Value, p.Key, values, RouteDirection.IncomingRequest)) - return null; + if (!ProcessConstraints (httpContext, values, RouteDirection.IncomingRequest)) + return null; var rd = new RouteData (this, RouteHandler); RouteValueDictionary rdValues = rd.Values; @@ -135,14 +132,27 @@ namespace System.Web.Routing // if (values == null) // values = requestContext.RouteData.Values; - string s; - if (!url.BuildUrl (this, requestContext, values, out s)) + RouteValueDictionary usedValues; + string resultUrl = url.BuildUrl (this, requestContext, values, Constraints, out usedValues); + + if (resultUrl == null) + return null; + + if (!ProcessConstraints (requestContext.HttpContext, usedValues, RouteDirection.UrlGeneration)) return null; - return new VirtualPathData (this, s); + var result = new VirtualPathData (this, resultUrl); + + RouteValueDictionary dataTokens = DataTokens; + if (dataTokens != null) { + foreach (var item in dataTokens) + result.DataTokens[item.Key] = item.Value; + } + + return result; } - internal static bool ProcessConstraintInternal (HttpContextBase httpContext, Route route, object constraint, string parameterName, + private bool ProcessConstraintInternal (HttpContextBase httpContext, Route route, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection, RequestContext reqContext, out bool invalidConstraint) { @@ -203,7 +213,7 @@ namespace System.Web.Routing constraint += "$"; } - return Regex.Match (value, constraint).Success; + return Regex.IsMatch (value, constraint, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled); } protected virtual bool ProcessConstraint (HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) @@ -234,6 +244,20 @@ namespace System.Web.Routing return ret; } + + private bool ProcessConstraints (HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection) + { + var constraints = Constraints; + + if (Constraints != null) { + foreach (var p in constraints) + if (!ProcessConstraint (httpContext, p.Value, p.Key, values, routeDirection)) + return false; + } + + return true; + } + #if NET_4_0 RequestContext SafeGetContext (HttpRequestBase req) { diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/HttpMethodConstraintTest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/HttpMethodConstraintTest.cs index 44f12551055..85a4273f7b8 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/HttpMethodConstraintTest.cs +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/HttpMethodConstraintTest.cs @@ -99,7 +99,7 @@ namespace MonoTests.System.Web.Routing public void Match () { var c = new MyHttpMethodConstraint (new string [0]); - Assert.IsFalse (c.CallMatch (new HttpContextStub (), new Route (null, null), "foo", new RouteValueDictionary (), RouteDirection.IncomingRequest)); + Assert.IsFalse (c.CallMatch (new HttpContextStub (""), new Route (null, null), "foo", new RouteValueDictionary (), RouteDirection.IncomingRequest)); } [Test] @@ -121,5 +121,18 @@ namespace MonoTests.System.Web.Routing // LAMESPEC: .NET allows case-insensitive comparison, which violates RFC 2616 // Assert.IsFalse (c.CallMatch (new HttpContextStub ("", "", "get"), new Route (null, null), "", new RouteValueDictionary (), RouteDirection.IncomingRequest), "#4"); } + + [Test] + public void UrlGeneration () + { + var c = new HttpMethodConstraint (new string[] { "GET" }) as IRouteConstraint; + var req = new HttpContextStub ("", "", "HEAD"); + + var values = new RouteValueDictionary () { { "httpMethod", "GET" } }; + Assert.IsTrue (c.Match (req, new Route (null, null), "httpMethod", values, RouteDirection.UrlGeneration), "#1"); + + values = new RouteValueDictionary() { { "httpMethod", "POST" } }; + Assert.IsFalse (c.Match (req, new Route (null, null), "httpMethod", values, RouteDirection.UrlGeneration), "#2"); + } } } diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs index 5310aafbbf1..18b52ea11ba 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs @@ -537,6 +537,63 @@ namespace MonoTests.System.Web.Routing Assert.IsNull (vp, "#C1"); } + [Test] + public void GetVirtualPath8 () + { + var routes = new RouteCollection(); + + routes.Add (new MyRoute ("login", new MyRouteHandler ()) { + Defaults = new RouteValueDictionary (new { controller = "Home", action = "LogOn" }) + }); + + routes.Add (new MyRoute ("{site}/{controller}/{action}", new MyRouteHandler ()) { + Defaults = new RouteValueDictionary (new { site = "_", controller = "Home", action = "Index" }), + Constraints = new RouteValueDictionary ( new { site = "_?[0-9A-Za-z-]*" }) + }); + + routes.Add (new MyRoute ("{*path}", new MyRouteHandler ()) { + Defaults = new RouteValueDictionary (new { controller = "Error", action = "NotFound" }), + }); + + var hc = new HttpContextStub2 ("~/login", String.Empty, String.Empty); + hc.SetResponse (new HttpResponseStub (3)); + var rd = routes.GetRouteData (hc); + var rvs = new RouteValueDictionary () { + { "controller", "Home" }, + { "action" , "Index" } + }; + var vpd = routes.GetVirtualPath (new RequestContext (hc, rd), rvs); + Assert.IsNotNull (vpd, "#A1"); + Assert.AreEqual ("/", vpd.VirtualPath, "#A2"); + Assert.AreEqual (0, vpd.DataTokens.Count, "#A3"); + + hc = new HttpContextStub2 ("~/login", String.Empty, String.Empty); + hc.SetResponse (new HttpResponseStub (3)); + rd = routes.GetRouteData (hc); + rvs = new RouteValueDictionary () { + { "controller", "Home" } + }; + vpd = routes.GetVirtualPath (new RequestContext (hc, rd), rvs); + Assert.IsNotNull (vpd, "#B1"); + Assert.AreEqual ("/login", vpd.VirtualPath, "#B2"); + Assert.AreEqual (0, vpd.DataTokens.Count, "#B3"); + + hc = new HttpContextStub2 ("~/login", String.Empty, String.Empty); + hc.SetResponse (new HttpResponseStub (3)); + rd = routes.GetRouteData (hc); + rvs = new RouteValueDictionary () { + { "action" , "Index" } + }; + vpd = routes.GetVirtualPath (new RequestContext (hc, rd), rvs); + Assert.IsNotNull (vpd, "#C1"); + Assert.AreEqual ("/", vpd.VirtualPath, "#C2"); + Assert.AreEqual (0, vpd.DataTokens.Count, "#C3"); + + hc = new HttpContextStub2 ("~/", String.Empty, String.Empty); + rd = routes.GetRouteData (hc); + Assert.IsNotNull (rd, "#D1"); + } + [Test] [Ignore ("looks like RouteExistingFiles ( = false) does not affect... so this test needs more investigation")] public void GetVirtualPathToExistingFile () diff --git a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs index a2852749c1a..ab9765ea6a4 100644 --- a/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs +++ b/mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteTest.cs @@ -974,12 +974,68 @@ namespace MonoTests.System.Web.Routing }) }; - var hc = new HttpContextStub ("/Foo/x123", String.Empty); + var hc = new HttpContextStub ("~/Foo/x123", String.Empty); var rd = r.GetRouteData (hc); Assert.IsNull (rd, "#1"); } - + + [Test] + public void GetRouteDataWithCatchAll () + { + var r = new Route ("{*path}", new StopRoutingHandler ()) { + Defaults = new RouteValueDictionary (new { + controller = "Error", + action = "NotFound" + }) + }; + + var hc = new HttpContextStub ("~/", String.Empty); + var rd = r.GetRouteData (hc); + + Assert.IsNotNull (rd, "#1"); + + hc = new HttpContextStub ("~/Foo/x123", String.Empty); + rd = r.GetRouteData (hc); + + Assert.IsNotNull (rd, "#2"); + } + + [Test] + public void GetRouteDataWithCatchAll2 () + { + var r = new Route ("something/{*path}", new StopRoutingHandler ()) { + Defaults = new RouteValueDictionary (new { + controller = "Error", + action = "NotFound" + }) + }; + + var hc = new HttpContextStub ("~/", String.Empty); + var rd = r.GetRouteData (hc); + + Assert.IsNull (rd, "#1"); + + hc = new HttpContextStub ("~/something", String.Empty); + rd = r.GetRouteData (hc); + + Assert.IsNotNull (rd, "#2"); + Assert.IsNull (rd.Values["path"], "#2.1"); + + hc = new HttpContextStub ("~/something/", String.Empty); + rd = r.GetRouteData (hc); + + Assert.IsNotNull (rd, "#3"); + Assert.IsNull (rd.Values["path"], "#3.1"); + + hc = new HttpContextStub ("~/something/algo", String.Empty); + rd = r.GetRouteData (hc); + + Assert.IsNotNull (rd, "#4"); + Assert.AreEqual ("algo", rd.Values["path"], "#4.1"); + + } + [Test] [ExpectedException (typeof (ArgumentNullException))] public void GetVirtualPathNullContext () diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs index e9888f11484..63c87fe7df4 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs @@ -247,7 +247,8 @@ namespace System.Xml.Serialization { XmlTypeMapping CreateTypeMapping (TypeData typeData, XmlRootAttribute root, string defaultXmlType, string defaultNamespace) { - string rootNamespace = defaultNamespace; + bool hasTypeNamespace = !string.IsNullOrEmpty (defaultNamespace); + string rootNamespace = null; string typeNamespace = null; string elementName; bool includeInSchema = true; @@ -273,8 +274,10 @@ namespace System.Xml.Serialization { if (atts.XmlType != null) { - if (atts.XmlType.Namespace != null) + if (atts.XmlType.Namespace != null) { typeNamespace = atts.XmlType.Namespace; + hasTypeNamespace = true; + } if (atts.XmlType.TypeName != null && atts.XmlType.TypeName != string.Empty) defaultXmlType = XmlConvert.EncodeLocalName (atts.XmlType.TypeName); @@ -288,13 +291,15 @@ namespace System.Xml.Serialization { { if (root.ElementName.Length != 0) elementName = XmlConvert.EncodeLocalName(root.ElementName); - if (root.Namespace != null) + if (root.Namespace != null) { rootNamespace = root.Namespace; + hasTypeNamespace = true; + } nullable = root.IsNullable; } - if (rootNamespace == null) rootNamespace = ""; - if (typeNamespace == null) typeNamespace = rootNamespace; + rootNamespace = rootNamespace ?? defaultNamespace ?? string.Empty; + typeNamespace = typeNamespace ?? rootNamespace; XmlTypeMapping map; switch (typeData.SchemaType) { @@ -310,7 +315,7 @@ namespace System.Xml.Serialization { typeData, defaultXmlType, typeNamespace); break; default: - map = new XmlTypeMapping (elementName, rootNamespace, typeData, defaultXmlType, typeNamespace); + map = new XmlTypeMapping (elementName, rootNamespace, typeData, defaultXmlType, hasTypeNamespace ? typeNamespace : null); break; } @@ -368,7 +373,8 @@ namespace System.Xml.Serialization { if (rmember.XmlAttributes.XmlIgnore) continue; if (rmember.DeclaringType != null && rmember.DeclaringType != type) { XmlTypeMapping bmap = ImportClassMapping (rmember.DeclaringType, root, defaultNamespace); - ns = bmap.XmlTypeNamespace; + if (bmap.HasXmlTypeNamespace) + ns = bmap.XmlTypeNamespace; } try { diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs index fc29513df6d..859042fd7e3 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs @@ -107,10 +107,15 @@ namespace System.Xml.Serialization internal string XmlTypeNamespace { - get { return xmlTypeNamespace; } + get { return xmlTypeNamespace ?? string.Empty; } set { xmlTypeNamespace = value; } } + internal bool HasXmlTypeNamespace + { + get { return xmlTypeNamespace != null; } + } + internal ArrayList DerivedTypes { get { return _derivedTypes; } @@ -170,9 +175,9 @@ namespace System.Xml.Serialization internal XmlTypeMapping GetRealElementMap (string name, string ens) { - if (xmlType == name && xmlTypeNamespace == ens) return this; + if (xmlType == name && XmlTypeNamespace == ens) return this; foreach (XmlTypeMapping map in _derivedTypes) - if (map.xmlType == name && map.xmlTypeNamespace == ens) return map; + if (map.xmlType == name && map.XmlTypeNamespace == ens) return map; return null; } diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/DeserializeTests.cs b/mcs/class/System.XML/Test/System.Xml.Serialization/DeserializeTests.cs index 459620cb13f..362d61fbcf7 100644 --- a/mcs/class/System.XML/Test/System.Xml.Serialization/DeserializeTests.cs +++ b/mcs/class/System.XML/Test/System.Xml.Serialization/DeserializeTests.cs @@ -1621,5 +1621,48 @@ namespace MonoTests.System.XmlSerialization Assert.IsNull(foobar.Baz); } } + + [Test] // bug #8468 + public void TestUseSubclassDefaultNamespace () + { + XmlSerializer xs = new XmlSerializer (typeof (Bug8468Subclass)); + string msg = "BaseValueMidValue"; + var res1 = (Bug8468Subclass)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res1); + Assert.AreEqual ("BaseValue", res1.Base); + Assert.AreEqual ("MidValue", res1.Mid); + + xs = new XmlSerializer (typeof (Bug8468SubclassNoNamespace), "http://test-namespace"); + var res2 = (Bug8468SubclassNoNamespace)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res2); + Assert.AreEqual ("BaseValue", res2.Base); + Assert.AreEqual ("MidValue", res2.Mid); + + xs = new XmlSerializer (typeof (Bug8468SubclassV2)); + var res3 = (Bug8468SubclassV2)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res3); + Assert.IsNull (res3.Base); + Assert.AreEqual ("MidValue", res3.Mid); + + xs = new XmlSerializer (typeof (Bug8468SubclassNoNamespaceV2), "http://test-namespace"); + var res4 = (Bug8468SubclassNoNamespaceV2)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res4); + Assert.IsNull (res4.Base); + Assert.AreEqual ("MidValue", res4.Mid); + + msg = "BaseValueMidValue"; + + xs = new XmlSerializer (typeof (Bug8468SubclassV2)); + var res5 = (Bug8468SubclassV2)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res5); + Assert.AreEqual ("BaseValue", res5.Base); + Assert.AreEqual ("MidValue", res5.Mid); + + xs = new XmlSerializer (typeof (Bug8468SubclassNoNamespaceV2), "http://test-namespace"); + var res6 = (Bug8468SubclassNoNamespaceV2)xs.Deserialize (new StringReader (msg)); + Assert.IsNotNull (res6); + Assert.AreEqual ("BaseValue", res6.Base); + Assert.AreEqual ("MidValue", res6.Mid); + } } } diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs index 955a8e3f7cb..006202d5860 100644 --- a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs +++ b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs @@ -1053,5 +1053,46 @@ namespace MonoTests.System.Xml.TestClasses [XmlElementAttribute (DataType = "date")] public DateTime SomeDate; } + + public class Bug8468BaseClass + { + public string Base; + } + + public class Bug8468MidClass: Bug8468BaseClass + { + public string Mid; + } + + [XmlRoot("Test", Namespace="http://test-namespace")] + public class Bug8468Subclass: Bug8468MidClass + { + } + + [XmlRoot("Test")] + public class Bug8468SubclassNoNamespace: Bug8468MidClass + { + } + + [XmlRoot("Test", Namespace="")] + public class Bug8468BaseClassV2 + { + public string Base; + } + + public class Bug8468MidClassV2: Bug8468BaseClassV2 + { + public string Mid; + } + + [XmlRoot("Test", Namespace="http://test-namespace")] + public class Bug8468SubclassV2: Bug8468MidClassV2 + { + } + + [XmlRoot("Test")] + public class Bug8468SubclassNoNamespaceV2: Bug8468MidClassV2 + { + } } diff --git a/mcs/class/System/Documentation/en/System.Threading/SemaphoreFullException.xml b/mcs/class/System/Documentation/en/System.Threading/SemaphoreFullException.xml deleted file mode 100644 index 0da24828bd6..00000000000 --- a/mcs/class/System/Documentation/en/System.Threading/SemaphoreFullException.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - System - 2.0.0.0 - - - System.SystemException - - - - - System.Runtime.InteropServices.ComVisible(false) - - - - To be added. - To be added. - - - - - - Constructor - - - To be added. - To be added. - - - - 2.0.0.0 - - - - - Constructor - - - - - To be added. - To be added. - To be added. - - - - 2.0.0.0 - - - - - Constructor - - - - - - To be added. - To be added. - To be added. - To be added. - - - - 2.0.0.0 - - - - - Constructor - - - - - - To be added. - To be added. - To be added. - To be added. - - - - 2.0.0.0 - - - - diff --git a/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs b/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs index 716beaaa851..26039bdd79b 100644 --- a/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs +++ b/mcs/class/System/Microsoft.CSharp/CSharpCodeCompiler.cs @@ -381,8 +381,10 @@ namespace Mono.CSharp break; } } - -#if NET_4_0 + +#if NET_4_5 + args.Append("/sdk:4.5"); +#elif NET_4_0 args.Append("/sdk:4"); #else args.Append("/sdk:2"); diff --git a/mcs/class/System/Mono.Http/NtlmClient.cs b/mcs/class/System/Mono.Http/NtlmClient.cs index 07f0fbc1e6a..f1b678827f2 100644 --- a/mcs/class/System/Mono.Http/NtlmClient.cs +++ b/mcs/class/System/Mono.Http/NtlmClient.cs @@ -76,6 +76,7 @@ namespace Mono.Http Type1Message type1 = new Type1Message (); type1.Domain = domain; type1.Host = ""; // MS does not send it + type1.Flags |= NtlmFlags.NegotiateNtlm2Key; message = type1; } else if (message.Type == 1) { // Should I check the credentials? @@ -88,11 +89,8 @@ namespace Mono.Http if (password == null) password = ""; - Type3Message type3 = new Type3Message (); - type3.Domain = domain; - // type3.Host = ""; MS sends the machine name for type 3 packets + Type3Message type3 = new Type3Message (type2); type3.Username = userName; - type3.Challenge = type2.Nonce; type3.Password = password; message = type3; completed = true; diff --git a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs index e5fb5ad7f59..b72c5eabc9d 100644 --- a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs +++ b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs @@ -23,7 +23,7 @@ // // -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Threading; diff --git a/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs b/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs index 5998c061ab0..233662a8d77 100644 --- a/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs +++ b/mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/System/System.Collections.Generic/ISet.cs b/mcs/class/System/System.Collections.Generic/ISet.cs index 61183792a5b..ec30f9d7837 100644 --- a/mcs/class/System/System.Collections.Generic/ISet.cs +++ b/mcs/class/System/System.Collections.Generic/ISet.cs @@ -25,7 +25,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_2_1 || NET_4_0 +#if NET_2_1 || MOBILE || NET_4_0 namespace System.Collections.Generic { public interface ISet : ICollection diff --git a/mcs/class/System/System.Configuration/ApplicationSettingsBase.cs b/mcs/class/System/System.Configuration/ApplicationSettingsBase.cs index 79b3308feb6..5b88dfd5af5 100644 --- a/mcs/class/System/System.Configuration/ApplicationSettingsBase.cs +++ b/mcs/class/System/System.Configuration/ApplicationSettingsBase.cs @@ -84,8 +84,7 @@ namespace System.Configuration { #if (CONFIGURATION_DEP) foreach (SettingsProvider provider in Providers) { IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider; - if (iasp != null) - iasp.Reset (Context); + CacheValuesByProvider(provider); } #endif } @@ -93,14 +92,9 @@ namespace System.Configuration { public void Reset() { #if (CONFIGURATION_DEP) - // Code bellow is identical to code in Reload(). - // foreach (SettingsProvider provider in Providers) { - // IApplicationSettingsProvider iasp = provider as IApplicationSettingsProvider; - // if (iasp != null) - // iasp.Reset (Context); - // } - Reload (); + foreach (SettingsPropertyValue pv in PropertyValues) + pv.PropertyValue = pv.Reset(); #endif } @@ -190,7 +184,12 @@ namespace System.Configuration { if (col.Count > 0) { SettingsPropertyValueCollection vals = provider.GetPropertyValues (Context, col); - PropertyValues.Add (vals); + foreach (SettingsPropertyValue prop in vals) { + if (PropertyValues [prop.Name] != null) + PropertyValues [prop.Name].PropertyValue = prop.PropertyValue; + else + PropertyValues.Add (prop); + } } OnSettingsLoaded (this, new SettingsLoadedEventArgs (provider)); diff --git a/mcs/class/System/System.Configuration/CustomizableFileSettingsProvider.cs b/mcs/class/System/System.Configuration/CustomizableFileSettingsProvider.cs index 7d70eefabbc..2ee1c984503 100644 --- a/mcs/class/System/System.Configuration/CustomizableFileSettingsProvider.cs +++ b/mcs/class/System/System.Configuration/CustomizableFileSettingsProvider.cs @@ -615,47 +615,49 @@ namespace System.Configuration if (userGroup == null) { userGroup = new UserSettingsGroup (); config.SectionGroups.Add ("userSettings", userGroup); - ApplicationSettingsBase asb = context.CurrentSettings; - ClientSettingsSection cs = new ClientSettingsSection (); - string class_name = NormalizeInvalidXmlChars ((asb != null ? asb.GetType () : typeof (ApplicationSettingsBase)).FullName); - userGroup.Sections.Add (class_name, cs); + } + ApplicationSettingsBase asb = context.CurrentSettings; + string class_name = NormalizeInvalidXmlChars ((asb != null ? asb.GetType () : typeof (ApplicationSettingsBase)).FullName); + ClientSettingsSection userSection = null; + ConfigurationSection cnf = userGroup.Sections.Get (class_name); + userSection = cnf as ClientSettingsSection; + if (userSection == null) { + userSection = new ClientSettingsSection (); + userGroup.Sections.Add (class_name, userSection); } bool hasChanges = false; - foreach (ConfigurationSection section in userGroup.Sections) { - ClientSettingsSection userSection = section as ClientSettingsSection; - if (userSection == null) - continue; + if (userSection == null) + return; - foreach (SettingsPropertyValue value in collection) { - if (checkUserLevel && value.Property.Attributes.Contains (typeof (SettingsManageabilityAttribute)) != isRoaming) - continue; - // The default impl does not save the ApplicationScopedSetting properties - if (value.Property.Attributes.Contains (typeof (ApplicationScopedSettingAttribute))) - continue; + foreach (SettingsPropertyValue value in collection) { + if (checkUserLevel && value.Property.Attributes.Contains (typeof (SettingsManageabilityAttribute)) != isRoaming) + continue; + // The default impl does not save the ApplicationScopedSetting properties + if (value.Property.Attributes.Contains (typeof (ApplicationScopedSettingAttribute))) + continue; - hasChanges = true; - SettingElement element = userSection.Settings.Get (value.Name); - if (element == null) { - element = new SettingElement (value.Name, value.Property.SerializeAs); - userSection.Settings.Add (element); - } - if (element.Value.ValueXml == null) - element.Value.ValueXml = new XmlDocument ().CreateElement ("value"); - switch (value.Property.SerializeAs) { - case SettingsSerializeAs.Xml: - element.Value.ValueXml.InnerXml = (value.SerializedValue as string) ?? string.Empty; - break; - case SettingsSerializeAs.String: - element.Value.ValueXml.InnerText = value.SerializedValue as string; - break; - case SettingsSerializeAs.Binary: - element.Value.ValueXml.InnerText = value.SerializedValue != null ? Convert.ToBase64String (value.SerializedValue as byte []) : string.Empty; - break; - default: - throw new NotImplementedException (); - } + hasChanges = true; + SettingElement element = userSection.Settings.Get (value.Name); + if (element == null) { + element = new SettingElement (value.Name, value.Property.SerializeAs); + userSection.Settings.Add (element); + } + if (element.Value.ValueXml == null) + element.Value.ValueXml = new XmlDocument ().CreateElement ("value"); + switch (value.Property.SerializeAs) { + case SettingsSerializeAs.Xml: + element.Value.ValueXml.InnerXml = (value.SerializedValue as string) ?? string.Empty; + break; + case SettingsSerializeAs.String: + element.Value.ValueXml.InnerText = value.SerializedValue as string; + break; + case SettingsSerializeAs.Binary: + element.Value.ValueXml.InnerText = value.SerializedValue != null ? Convert.ToBase64String (value.SerializedValue as byte []) : string.Empty; + break; + default: + throw new NotImplementedException (); } } if (hasChanges) @@ -792,21 +794,19 @@ namespace System.Configuration { CreateExeMap (); - if (values == null) { - values = new SettingsPropertyValueCollection (); - string groupName = context ["GroupName"] as string; - groupName = NormalizeInvalidXmlChars (groupName); // we likely saved the element removing the non valid xml chars. - LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "applicationSettings", false, groupName); - LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "userSettings", false, groupName); + values = new SettingsPropertyValueCollection (); + string groupName = context ["GroupName"] as string; + groupName = NormalizeInvalidXmlChars (groupName); // we likely saved the element removing the non valid xml chars. + LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "applicationSettings", false, groupName); + LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "userSettings", false, groupName); - LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoaming, "userSettings", true, groupName); - LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoamingAndLocal, "userSettings", true, groupName); + LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoaming, "userSettings", true, groupName); + LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoamingAndLocal, "userSettings", true, groupName); - // create default values if not exist - foreach (SettingsProperty p in collection) - if (values [p.Name] == null) - values.Add (new SettingsPropertyValue (p)); - } + // create default values if not exist + foreach (SettingsProperty p in collection) + if (values [p.Name] == null) + values.Add (new SettingsPropertyValue (p)); return values; } @@ -859,13 +859,14 @@ namespace System.Configuration public void Reset (SettingsContext context) { SettingsPropertyCollection coll = new SettingsPropertyCollection (); - GetPropertyValues (context, coll); - foreach (SettingsPropertyValue propertyValue in values) { - // Can't use propertyValue.Property.DefaultValue - // as it may cause InvalidCastException (see bug# 532180) - propertyValue.PropertyValue = propertyValue.Reset (); + // GetPropertyValues (context, coll); + if (values != null) { + foreach (SettingsPropertyValue propertyValue in values) { + // Can't use propertyValue.Property.DefaultValue + // as it may cause InvalidCastException (see bug# 532180) + values[propertyValue.Name].PropertyValue = propertyValue.Reset (); + } } - SetPropertyValues (context, values); } // FIXME: implement diff --git a/mcs/class/System/System.Configuration/SettingsPropertyValue.cs b/mcs/class/System/System.Configuration/SettingsPropertyValue.cs index 2d554cc7571..9bf62c00c62 100644 --- a/mcs/class/System/System.Configuration/SettingsPropertyValue.cs +++ b/mcs/class/System/System.Configuration/SettingsPropertyValue.cs @@ -171,7 +171,7 @@ namespace System.Configuration private object GetDeserializedDefaultValue () { if (property.DefaultValue == null) - if (property.PropertyType.IsValueType) + if (property.PropertyType != null && property.PropertyType.IsValueType) return Activator.CreateInstance (property.PropertyType); else return null; diff --git a/mcs/class/System/System.Diagnostics/Win32EventLog.cs b/mcs/class/System/System.Diagnostics/Win32EventLog.cs index c3f68c8b789..40fe3a36b15 100644 --- a/mcs/class/System/System.Diagnostics/Win32EventLog.cs +++ b/mcs/class/System/System.Diagnostics/Win32EventLog.cs @@ -794,10 +794,10 @@ namespace System.Diagnostics [DllImport ("advapi32.dll", SetLastError=true)] public static extern int DeregisterEventSource (IntPtr hEventLog); - [DllImport ("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] + [DllImport ("kernel32", CharSet=CharSet.Auto, SetLastError=true)] public static extern int FormatMessage (FormatMessageFlags dwFlags, IntPtr lpSource, uint dwMessageId, int dwLanguageId, ref IntPtr lpBuffer, int nSize, IntPtr [] arguments); - [DllImport ("kernel32.dll", SetLastError=true)] + [DllImport ("kernel32", SetLastError=true)] public static extern bool FreeLibrary (IntPtr hModule); [DllImport ("advapi32.dll", SetLastError=true)] @@ -806,10 +806,10 @@ namespace System.Diagnostics [DllImport ("advapi32.dll", SetLastError=true)] public static extern int GetOldestEventLogRecord (IntPtr hEventLog, ref int OldestRecord); - [DllImport ("kernel32.dll", SetLastError=true)] + [DllImport ("kernel32", SetLastError=true)] public static extern IntPtr LoadLibraryEx (string lpFileName, IntPtr hFile, LoadFlags dwFlags); - [DllImport ("kernel32.dll", SetLastError=true)] + [DllImport ("kernel32", SetLastError=true)] public static extern IntPtr LocalFree (IntPtr hMem); [DllImport ("advapi32.dll", SetLastError=true)] @@ -822,7 +822,7 @@ namespace System.Diagnostics ref uint cchReferencedDomainName, out SidNameUse peUse); - [DllImport ("Advapi32.dll", SetLastError = true)] + [DllImport ("advapi32.dll", SetLastError = true)] public static extern int NotifyChangeEventLog (IntPtr hEventLog, IntPtr hEvent); [DllImport ("advapi32.dll", SetLastError=true)] @@ -831,7 +831,7 @@ namespace System.Diagnostics [DllImport ("advapi32.dll", SetLastError=true)] public static extern IntPtr RegisterEventSource (string machineName, string sourceName); - [DllImport ("Advapi32.dll", SetLastError=true)] + [DllImport ("advapi32.dll", SetLastError=true)] public static extern int ReportEvent (IntPtr hHandle, ushort wType, ushort wCategory, uint dwEventID, IntPtr sid, ushort wNumStrings, uint dwDataSize, string [] lpStrings, byte [] lpRawData); diff --git a/mcs/class/System/System.IO.Ports/WinSerialStream.cs b/mcs/class/System/System.IO.Ports/WinSerialStream.cs index f30973fc346..fc0d45dbd20 100644 --- a/mcs/class/System/System.IO.Ports/WinSerialStream.cs +++ b/mcs/class/System/System.IO.Ports/WinSerialStream.cs @@ -23,8 +23,8 @@ namespace System.IO.Ports const uint GenericWrite = 0x40000000; const uint OpenExisting = 3; const uint FileFlagOverlapped = 0x40000000; - const uint PurgeRxClear = 0x0004; - const uint PurgeTxClear = 0x0008; + const uint PurgeRxClear = 0x0008; + const uint PurgeTxClear = 0x0004; const uint WinInfiniteTimeout = 0xFFFFFFFF; const uint FileIOPending = 997; @@ -375,7 +375,7 @@ namespace System.IO.Ports public void DiscardOutBuffer () { - if (!PurgeComm (handle, PurgeRxClear)) + if (!PurgeComm (handle, PurgeTxClear)) ReportIOError (null); } diff --git a/mcs/class/System/System.Media/AudioData.cs b/mcs/class/System/System.Media/AudioData.cs index d44d2338cb7..dd90140a1a6 100644 --- a/mcs/class/System/System.Media/AudioData.cs +++ b/mcs/class/System/System.Media/AudioData.cs @@ -12,7 +12,7 @@ namespace Mono.Audio { #endif abstract class AudioData { protected const int buffer_size = 4096; - bool stopped = false; + bool stopped; public abstract int Channels { get; @@ -58,8 +58,8 @@ namespace Mono.Audio { short channels; ushort frame_divider; int sample_rate; - int data_len = 0; - long data_offset = 0; + int data_len; + long data_offset; AudioFormat format; public WavData (Stream data) { @@ -100,7 +100,7 @@ namespace Mono.Audio { byte_rate |= buffer [idx++] << 8; byte_rate |= buffer [idx++] << 16; byte_rate |= buffer [idx++] << 24; - int block_align = buffer [idx++] | (buffer [idx++] << 8); +// int block_align = buffer [idx++] | (buffer [idx++] << 8); int sign_bits = buffer [idx++] | (buffer [idx++] << 8); switch (sign_bits) { @@ -203,8 +203,8 @@ namespace Mono.Audio { short channels; ushort frame_divider; int sample_rate; - int data_len = 0; - int data_offset = 0; + int data_len ; +// int data_offset; AudioFormat format; public AuData (Stream data) { @@ -265,7 +265,7 @@ namespace Mono.Audio { byte[] chunk_to_play = new byte [chunk_size]; // Read only Au data, don't care about file header here ! - stream.Position = (long)data_offset; + stream.Position = 0; //(long)data_offset; stream.Read (buffer, 0, data_len); while (!IsStopped && count >= 0){ diff --git a/mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs b/mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs index 5946766b5b2..fb4d22a6c87 100644 --- a/mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs +++ b/mcs/class/System/System.Net.NetworkInformation/IPGlobalProperties.cs @@ -550,31 +550,31 @@ namespace System.Net.NetworkInformation { // PInvokes - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetTcpTable (byte [] pTcpTable, ref int pdwSize, bool bOrder); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetTcp6Table (byte [] TcpTable, ref int SizePointer, bool Order); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetUdpTable (byte [] pUdpTable, ref int pdwSize, bool bOrder); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetUdp6Table (byte [] Udp6Table, ref int SizePointer, bool Order); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetTcpStatisticsEx (out Win32_MIB_TCPSTATS pStats, int dwFamily); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetUdpStatisticsEx (out Win32_MIB_UDPSTATS pStats, int dwFamily); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetIcmpStatistics (out Win32_MIBICMPINFO pStats, int dwFamily); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetIcmpStatisticsEx (out Win32_MIB_ICMP_EX pStats, int dwFamily); - [DllImport ("Iphlpapi.dll")] + [DllImport ("iphlpapi.dll")] static extern int GetIpStatisticsEx (out Win32_MIB_IPSTATS pStats, int dwFamily); // Win32 structures diff --git a/mcs/class/System/System.Net.Sockets/NetworkStream.cs b/mcs/class/System/System.Net.Sockets/NetworkStream.cs index b51e5050ce7..65126ca24f2 100644 --- a/mcs/class/System/System.Net.Sockets/NetworkStream.cs +++ b/mcs/class/System/System.Net.Sockets/NetworkStream.cs @@ -32,7 +32,7 @@ using System.IO; using System.Runtime.InteropServices; -#if !NET_2_1 +#if !NET_2_1 || MOBILE using System.Timers; using System.Threading; #endif @@ -142,7 +142,7 @@ namespace System.Net.Sockets } } -#if !NET_2_1 +#if !NET_2_1 || MOBILE #if TARGET_JVM [MonoNotSupported ("Not supported since Socket.ReceiveTimeout is not supported")] #endif @@ -178,7 +178,7 @@ namespace System.Net.Sockets } } -#if !NET_2_1 +#if !NET_2_1 || MOBILE #if TARGET_JVM [MonoNotSupported ("Not supported since Socket.SendTimeout is not supported")] #endif @@ -267,7 +267,7 @@ namespace System.Net.Sockets } -#if !NET_2_1 +#if !NET_2_1 || MOBILE public void Close (int timeout) { if (timeout < -1) { diff --git a/mcs/class/System/System.Net/WebConnection.cs b/mcs/class/System/System.Net/WebConnection.cs index 6ab7278c085..4922fb3291c 100644 --- a/mcs/class/System/System.Net/WebConnection.cs +++ b/mcs/class/System/System.Net/WebConnection.cs @@ -773,7 +773,11 @@ namespace System.Net request.SetWriteStream (new WebConnectionStream (this, request)); } - + +#if MONOTOUCH + static bool warned_about_queue = false; +#endif + internal EventHandler SendRequest (HttpWebRequest request) { if (request.Aborted) @@ -786,6 +790,12 @@ namespace System.Net ThreadPool.QueueUserWorkItem (initConn, request); } else { lock (queue) { +#if MONOTOUCH + if (!warned_about_queue) { + warned_about_queue = true; + Console.WriteLine ("WARNING: An HttpWebRequest was added to the ConnectionGroup queue because the connection limit was reached."); + } +#endif queue.Enqueue (request); } } diff --git a/mcs/class/System/System.Net/WebConnectionStream.cs b/mcs/class/System/System.Net/WebConnectionStream.cs index e952f2a0992..ff370e9e8ba 100644 --- a/mcs/class/System/System.Net/WebConnectionStream.cs +++ b/mcs/class/System/System.Net/WebConnectionStream.cs @@ -70,6 +70,12 @@ namespace System.Net public WebConnectionStream (WebConnection cnc) { + if (cnc.Data == null) + throw new InvalidOperationException ("cnc.Data was not initialized"); + if (cnc.Data.Headers == null) + throw new InvalidOperationException ("cnc.Data.Headers was not initialized"); + if (cnc.Data.request == null) + throw new InvalidOperationException ("cnc.Data.request was not initialized"); isRead = true; cb_wrapper = new AsyncCallback (ReadCallbackWrapper); pending = new ManualResetEvent (true); diff --git a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509ExtensionCollection.cs b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509ExtensionCollection.cs index 0013d96d9c7..948633d00d5 100644 --- a/mcs/class/System/System.Security.Cryptography.X509Certificates/X509ExtensionCollection.cs +++ b/mcs/class/System/System.Security.Cryptography.X509Certificates/X509ExtensionCollection.cs @@ -68,7 +68,7 @@ namespace System.Security.Cryptography.X509Certificates { raw_data = value [0].GetBytes (); X509Extension newt = null; -#if MOONLIGHT +#if MOONLIGHT || FULL_AOT_RUNTIME // non-extensible switch (oid) { case "2.5.29.14": diff --git a/mcs/class/System/System.Text.RegularExpressions/Regex.cs b/mcs/class/System/System.Text.RegularExpressions/Regex.cs index 9d18feabd0c..378a3b872fe 100644 --- a/mcs/class/System/System.Text.RegularExpressions/Regex.cs +++ b/mcs/class/System/System.Text.RegularExpressions/Regex.cs @@ -45,7 +45,7 @@ namespace System.Text.RegularExpressions { [Serializable] public partial class Regex : ISerializable { -#if !TARGET_JVM +#if !TARGET_JVM && !FULL_AOT_RUNTIME [MonoTODO] public static void CompileToAssembly (RegexCompilationInfo [] regexes, AssemblyName aname) { diff --git a/mcs/class/System/System.Threading/Barrier.cs b/mcs/class/System/System.Threading/Barrier.cs index 7e7e2c6849f..3117da4d3a0 100644 --- a/mcs/class/System/System.Threading/Barrier.cs +++ b/mcs/class/System/System.Threading/Barrier.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Diagnostics; diff --git a/mcs/class/System/System.Threading/BarrierPostPhaseException.cs b/mcs/class/System/System.Threading/BarrierPostPhaseException.cs index 70c5ed81a41..bcf4ddbc277 100644 --- a/mcs/class/System/System.Threading/BarrierPostPhaseException.cs +++ b/mcs/class/System/System.Threading/BarrierPostPhaseException.cs @@ -24,7 +24,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#if NET_4_0 +#if NET_4_0 || MOBILE using System; using System.Runtime.Serialization; diff --git a/mcs/class/System/System/Uri.cs b/mcs/class/System/System/Uri.cs index f56a59532e6..d57cb679c6c 100644 --- a/mcs/class/System/System/Uri.cs +++ b/mcs/class/System/System/Uri.cs @@ -1033,18 +1033,13 @@ namespace System { if (segments [k] != segments2 [k]) break; - for (int i = k + 1; i < segments.Length; i++) + for (int i = k; i < segments.Length && segments [i].EndsWith ("/"); i++) result += "../"; for (int i = k; i < segments2.Length; i++) result += segments2 [i]; - // if there is more than 1 segment and if the last segment of segments - // ends with separator char, assume its a directory and prepend "../" - if (segments.Length > 1) { - var lastSegment = segments [segments.Length - 1]; - if (lastSegment.EndsWith ("/")) - result = "../" + result; - } + if (result == string.Empty) + result = "./"; } uri.AppendQueryAndFragment (ref result); diff --git a/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs b/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs index 5763a0b9723..88be568f429 100644 --- a/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs +++ b/mcs/class/System/Test/System.ComponentModel/BindingListTest.cs @@ -585,6 +585,50 @@ namespace MonoTests.System.ComponentModel Assert.AreEqual (0, list_changed_index, "4"); Assert.AreEqual (1, poker.Count, "5"); } + + private class Item : INotifyPropertyChanged { + + public event PropertyChangedEventHandler PropertyChanged; + + string _name; + + public string Name { + get { return _name; } + set { + if (_name != value) { + _name = value; + OnPropertyChanged ("Name"); + } + } + } + + void OnPropertyChanged (string name) + { + var fn = PropertyChanged; + if (fn != null) + fn (this, new PropertyChangedEventArgs (name)); + } + } + + [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=8366 + public void Bug8366 () + { + bool added = false; + bool changed = false; + var list = new BindingList (); + list.ListChanged += (object sender, ListChangedEventArgs e) => { + added |= e.ListChangedType == ListChangedType.ItemAdded; + changed |= e.ListChangedType == ListChangedType.ItemChanged; + }; + + var item = new Item () { Name = "1" }; + list.Add (item); + + item.Name = "2"; + + Assert.IsTrue (added, "ItemAdded"); + Assert.IsTrue (changed, "ItemChanged"); + } } } diff --git a/mcs/class/System/Test/System.Configuration/ApplicationSettingsBaseTest.cs b/mcs/class/System/Test/System.Configuration/ApplicationSettingsBaseTest.cs index 4325fad2ff4..98d87d4ab98 100644 --- a/mcs/class/System/Test/System.Configuration/ApplicationSettingsBaseTest.cs +++ b/mcs/class/System/Test/System.Configuration/ApplicationSettingsBaseTest.cs @@ -379,14 +379,97 @@ namespace MonoTests.System.Configuration { } [Test] // bug #532180 - public void DefaultSettingValueAsWithReload() { + public void DefaultSettingValueAsWithReload() + { Bug532180 settings = new Bug532180(); - Assert.AreEqual(10, settings.IntSetting, "A1"); + Assert.AreEqual (10, settings.IntSetting, "A1"); settings.IntSetting = 1; - Assert.AreEqual(1, settings.IntSetting, "A2"); - settings.Reload(); - Assert.AreEqual(10, settings.IntSetting, "A3"); + Assert.AreEqual (1, settings.IntSetting, "A2"); + settings.Reload (); + Assert.AreEqual (10, settings.IntSetting, "A3"); } + + class Bug8592ConfHolder : ApplicationSettingsBase { + [UserScopedSetting] + public string TestKey1OnHolder { + get { return (string) this ["TestKey1OnHolder"] ?? ""; } + set { this ["TestKey1OnHolder"] = value; } + } + } + + [Test] + public void TestBug8592BasicOperations () + { + var holder = new Bug8592ConfHolder (); + holder.Reset (); + holder.Save (); + Assert.AreEqual ("", holder.TestKey1OnHolder); + holder.TestKey1OnHolder = "candy"; + Assert.AreEqual ("candy", holder.TestKey1OnHolder); + holder.Reload (); + Assert.AreEqual ("", holder.TestKey1OnHolder); + holder.TestKey1OnHolder = "candy"; + Assert.AreEqual ("candy", holder.TestKey1OnHolder); + holder.Save (); + Assert.AreEqual ("candy", holder.TestKey1OnHolder); + holder.Reload (); + Assert.AreEqual ("candy", holder.TestKey1OnHolder); + holder.Reset (); + Assert.AreEqual ("", holder.TestKey1OnHolder); + } + + class Bug8533ConfHolder1 : ApplicationSettingsBase { + [UserScopedSetting] + public string TestKey1OnHolder1 { + get { return (string) this ["TestKey1OnHolder1"] ?? ""; } + set { this ["TestKey1OnHolder1"] = value; } + } + + [UserScopedSetting] + public string TestKey1OnHolder2 { + get { return (string) this ["TestKey1OnHolder2"] ?? ""; } + set { this ["TestKey1OnHolder2"] = value; } + } + + [UserScopedSetting] + public string TestKey { + get { return (string) this ["TestKey"] ?? ""; } + set { this ["TestKey"] = value; } + } + } + + class Bug8533ConfHolder2 : ApplicationSettingsBase { + [UserScopedSetting] + public string TestKey1OnHolder2 { + get { return (string) this ["TestKey1OnHolder2"] ?? ""; } + set { this ["TestKey1OnHolder2"] = value; } + } + + [UserScopedSetting] + public string TestKey { + get { return (string) this ["TestKey"] ?? ""; } + set { this ["TestKey"] = value; } + } + } + + [Test] + public void TestBug8533ConfHandlerWronglyMixedUp () + { + var holder1 = new Bug8533ConfHolder1 (); + var holder2 = new Bug8533ConfHolder2 (); + holder1.TestKey1OnHolder1 = "candy"; + holder2.TestKey1OnHolder2 = "donut"; + holder1.TestKey = "eclair"; + holder1.Save (); + holder2.Save (); + holder1.Reload (); + holder2.Reload(); + Assert.AreEqual ("", holder1.TestKey1OnHolder2); + Assert.AreEqual ("candy", holder1.TestKey1OnHolder1); + Assert.AreEqual ("donut", holder2.TestKey1OnHolder2); + Assert.AreEqual ("eclair", holder1.TestKey); + Assert.AreEqual ("", holder2.TestKey); + } } } diff --git a/mcs/class/System/Test/System/UriTest3.cs b/mcs/class/System/Test/System/UriTest3.cs index cf06911489b..da4e7c4d550 100644 --- a/mcs/class/System/Test/System/UriTest3.cs +++ b/mcs/class/System/Test/System/UriTest3.cs @@ -441,6 +441,7 @@ namespace MonoTests.System Uri uri13 = new Uri ("mailto:xxx@xxx.com/foo/bar"); Uri uri14 = new Uri ("http://www.contoso.com/test1/"); Uri uri15 = new Uri ("http://www.contoso.com/"); + Uri uri16 = new Uri ("http://www.contoso.com/test"); AssertRelativeUri ("foo/bar/index.htm#fragment", uri1, uri2, "#A"); AssertRelativeUri ("../../index.htm?x=2", uri2, uri1, "#B"); @@ -474,6 +475,59 @@ namespace MonoTests.System Assert.AreEqual (uri5.OriginalString, relativeUri.OriginalString, "#N3"); AssertRelativeUri ("../", uri14, uri15, "#O"); + AssertRelativeUri ("./", uri16, uri15, "#P"); + + Uri a1 = new Uri ("http://something/something2/test/"); + Uri a2 = new Uri ("http://something/something2/"); + Uri a3 = new Uri ("http://something/something2/test"); + Uri a4 = new Uri ("http://something/something2"); + + AssertRelativeUri ("../", a1, a2, "Q1"); + AssertRelativeUri ("../../something2", a1, a4, "Q2"); + AssertRelativeUri ("./", a3, a2, "Q3"); + AssertRelativeUri ("../something2", a3, a4, "Q4"); + + Uri b1 = new Uri ("http://something/test/"); + Uri b2 = new Uri ("http://something/"); + Uri b3 = new Uri ("http://something/test"); + Uri b4 = new Uri ("http://something"); + + AssertRelativeUri ("../", b1, b2, "R1"); + AssertRelativeUri ("../", b1, b4, "R2"); + AssertRelativeUri ("./", b3, b2, "R3"); + AssertRelativeUri ("./", b3, b4, "R4"); + + Uri c1 = new Uri ("C:\\something\\something2\\test\\"); + Uri c2 = new Uri ("C:\\something\\something2\\"); + Uri c3 = new Uri ("C:\\something\\something2\\test"); + Uri c4 = new Uri ("C:\\something\\something2"); + + AssertRelativeUri ("../", c1, c2, "S1"); + AssertRelativeUri ("../../something2", c1, c4, "S2"); + AssertRelativeUri ("./", c3, c2, "S3"); + AssertRelativeUri ("../something2", c3, c4, "S4"); + + Uri d1 = new Uri ("C:\\something\\test\\"); + Uri d2 = new Uri ("C:\\something\\"); + Uri d3 = new Uri ("C:\\something\\test"); + Uri d4 = new Uri ("C:\\something"); + + AssertRelativeUri ("../", d1, d2, "T1"); + AssertRelativeUri ("../../something", d1, d4, "T2"); + AssertRelativeUri ("./", d3, d2, "T3"); + AssertRelativeUri ("../something", d3, d4, "T4"); + + Uri e1 = new Uri ("C:\\something\\"); + Uri e2 = new Uri ("C:\\"); + Uri e3 = new Uri ("C:\\something"); + + AssertRelativeUri ("../", e1, e2, "U1"); + AssertRelativeUri ("./", e3, e2, "U2"); + AssertRelativeUri ("", e1, e1, "U3"); + AssertRelativeUri ("", e3, e3, "U4"); + AssertRelativeUri ("../something", e1, e3, "U5"); + AssertRelativeUri ("something/", e3, e1, "U6"); + AssertRelativeUri ("something", e2, e3, "U7"); } [Test] diff --git a/mcs/class/System/mobile_System.dll.sources b/mcs/class/System/mobile_System.dll.sources index 00b640ae9fd..b83111b9907 100644 --- a/mcs/class/System/mobile_System.dll.sources +++ b/mcs/class/System/mobile_System.dll.sources @@ -4,6 +4,10 @@ ../corlib/System.Collections.Generic/CollectionDebuggerView.cs ../corlib/System.Collections/CollectionDebuggerView.cs ../corlib/Mono/DataConverter.cs +../corlib/System.Threading.Tasks/CyclicDeque.cs +../corlib/System.Threading.Tasks/IConcurrentDeque.cs +../corlib/System.Threading.Tasks/PopResult.cs +../corlib/System.Threading/AtomicBoolean.cs Assembly/AssemblyInfo.cs Mono.Http/NtlmClient.cs @@ -17,6 +21,8 @@ System.Collections.Generic/SortedDictionary.cs System.Collections.Generic/SortedList.cs System.Collections.Generic/SortedSet.cs System.Collections.Generic/Stack.cs +System.Collections.Concurrent/BlockingCollection.cs +System.Collections.Concurrent/ConcurrentBag.cs System.Collections.ObjectModel/ObservableCollection.cs System.Collections.ObjectModel/ReadOnlyObservableCollection.cs System.Collections.Specialized/BitVector32.cs @@ -60,6 +66,8 @@ System.ComponentModel.Design/MenuCommand.cs System.ComponentModel.Design/ServiceCreatorCallback.cs System.ComponentModel.Design/StandardCommands.cs System.ComponentModel.Design/ViewTechnology.cs +System.ComponentModel/AddingNewEventArgs.cs +System.ComponentModel/AddingNewEventHandler.cs System.ComponentModel/ArrayConverter.cs System.ComponentModel/AsyncCompletedEventArgs.cs System.ComponentModel/AsyncCompletedEventHandler.cs @@ -69,6 +77,7 @@ System.ComponentModel/AttributeCollection.cs System.ComponentModel/BackgroundWorker.cs System.ComponentModel/BaseNumberConverter.cs System.ComponentModel/BindableSupport.cs +System.ComponentModel/BindingList.cs System.ComponentModel/BooleanConverter.cs System.ComponentModel/BrowsableAttribute.cs System.ComponentModel/ByteConverter.cs @@ -111,6 +120,7 @@ System.ComponentModel/ExpandableObjectConverter.cs System.ComponentModel/GuidConverter.cs System.ComponentModel/IBindingList.cs System.ComponentModel/IBindingListView.cs +System.ComponentModel/ICancelAddNew.cs System.ComponentModel/IChangeTracking.cs System.ComponentModel/IComNativeDescriptorHandler.cs System.ComponentModel/IComponent.cs @@ -123,6 +133,7 @@ System.ComponentModel/IEditableObject.cs System.ComponentModel/IListSource.cs System.ComponentModel/INotifyPropertyChanged.cs System.ComponentModel/INotifyPropertyChanging.cs +System.ComponentModel/IRaiseItemChangedEvents.cs System.ComponentModel/IRevertibleChangeTracking.cs System.ComponentModel/ISite.cs System.ComponentModel/ISupportInitialize.cs @@ -449,6 +460,7 @@ System.Net/WebProxy.cs System.Net/WebRequest.cs System.Net/WebRequestMethods.cs System.Net/WebResponse.cs +System.Runtime.InteropServices/DefaultParameterValueAttribute.cs System.Security.AccessControl/SemaphoreAccessRule.cs System.Security.AccessControl/SemaphoreAuditRule.cs System.Security.AccessControl/SemaphoreRights.cs @@ -523,6 +535,8 @@ System.Text.RegularExpressions/parser.cs System.Text.RegularExpressions/quicksearch.cs System.Text.RegularExpressions/replace.cs System.Text.RegularExpressions/syntax.cs +System.Threading/Barrier.cs +System.Threading/BarrierPostPhaseException.cs System.Threading/Semaphore.cs System.Threading/SemaphoreFullException.cs System.Threading/ThreadExceptionEventArgs.cs @@ -555,4 +569,4 @@ System/UriPartial.cs System/UriTypeConverter.cs System/UriElements.cs System/UriParseComponents.cs -System.Windows.Input/ICommand.cs \ No newline at end of file +System.Windows.Input/ICommand.cs diff --git a/mcs/class/WindowsBase/System.Collections.Specialized/INotifyCollectionChanged.cs b/mcs/class/WindowsBase/System.Collections.Specialized/INotifyCollectionChanged.cs index e0d6a102ffd..eac7130d640 100644 --- a/mcs/class/WindowsBase/System.Collections.Specialized/INotifyCollectionChanged.cs +++ b/mcs/class/WindowsBase/System.Collections.Specialized/INotifyCollectionChanged.cs @@ -32,7 +32,6 @@ using System.Runtime.CompilerServices; #else using System; -using System.Windows; namespace System.Collections.Specialized { diff --git a/mcs/class/WindowsBase/System.ComponentModel/GroupDescription.cs b/mcs/class/WindowsBase/System.ComponentModel/GroupDescription.cs index 4cd981ae02b..ed9d824c339 100644 --- a/mcs/class/WindowsBase/System.ComponentModel/GroupDescription.cs +++ b/mcs/class/WindowsBase/System.ComponentModel/GroupDescription.cs @@ -33,7 +33,6 @@ namespace System.ComponentModel { { protected GroupDescription () { - throw new NotImplementedException (); } public ObservableCollection GroupNames { @@ -54,7 +53,8 @@ namespace System.ComponentModel { protected virtual void OnPropertyChanged (PropertyChangedEventArgs e) { - throw new NotImplementedException (); + if (PropertyChanged != null) + PropertyChanged (this, e); } [EditorBrowsable (EditorBrowsableState.Never)] diff --git a/mcs/class/WindowsBase/System.ComponentModel/IEditableCollectionViewAddNewItem.cs b/mcs/class/WindowsBase/System.ComponentModel/IEditableCollectionViewAddNewItem.cs new file mode 100644 index 00000000000..07f9c248d86 --- /dev/null +++ b/mcs/class/WindowsBase/System.ComponentModel/IEditableCollectionViewAddNewItem.cs @@ -0,0 +1,38 @@ +// +// IEditableCollectionViewAddNewItem.cs +// +// Author: +// Antonius Riha +// +// Copyright (c) 2012 Antonius Riha +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if NET_4_0 + +namespace System.ComponentModel +{ + public interface IEditableCollectionViewAddNewItem : IEditableCollectionView + { + bool CanAddNewItem { get; } + object AddNewItem (object newItem); + } +} + +#endif diff --git a/mcs/class/WindowsBase/WindowsBase-net_4_0.csproj b/mcs/class/WindowsBase/WindowsBase-net_4_0.csproj index 26a0197f53b..59c81c5be7b 100644 --- a/mcs/class/WindowsBase/WindowsBase-net_4_0.csproj +++ b/mcs/class/WindowsBase/WindowsBase-net_4_0.csproj @@ -58,6 +58,7 @@ + diff --git a/mcs/class/WindowsBase/WindowsBase-net_4_5.csproj b/mcs/class/WindowsBase/WindowsBase-net_4_5.csproj index 73fa0f8da88..78b5ba275de 100644 --- a/mcs/class/WindowsBase/WindowsBase-net_4_5.csproj +++ b/mcs/class/WindowsBase/WindowsBase-net_4_5.csproj @@ -58,6 +58,7 @@ + diff --git a/mcs/class/WindowsBase/WindowsBase.dll.sources b/mcs/class/WindowsBase/WindowsBase.dll.sources index 2e76f6e8a42..f0a6e5c2ab6 100644 --- a/mcs/class/WindowsBase/WindowsBase.dll.sources +++ b/mcs/class/WindowsBase/WindowsBase.dll.sources @@ -14,6 +14,7 @@ System.ComponentModel/GroupDescription.cs System.ComponentModel/ICollectionView.cs System.ComponentModel/ICollectionViewFactory.cs System.ComponentModel/IEditableCollectionView.cs +System.ComponentModel/IEditableCollectionViewAddNewItem.cs System.ComponentModel/IItemProperties.cs System.ComponentModel/ItemPropertyInfo.cs System.ComponentModel/NewItemPlaceholderPosition.cs diff --git a/mcs/class/build-rx-dll-sources.sh b/mcs/class/build-rx-dll-sources.sh new file mode 100644 index 00000000000..e12f2be893e --- /dev/null +++ b/mcs/class/build-rx-dll-sources.sh @@ -0,0 +1,80 @@ + +// useful grep +// grep -h "#if" /svn/mono/external/rx/Rx.NET/System.Reactive.*/*.cs /svn/mono/external/rx/Rx.NET/System.Reactive.*/*/*.cs /svn/mono/external/rx/Rx.NET/System.Reactive.*/*/*/*.cs | sort | uniq + +using System.Diagnostics; +using System.IO; +using System.Xml.Linq; +using System.Xml.XPath; + +var asses = new string [] { + "System.Reactive.Interfaces", + "System.Reactive.Core", + "System.Reactive.PlatformServices", + "System.Reactive.Linq", + "System.Reactive.Debugger", // maybe needed for testing assembly. + "System.Reactive.Experimental", // needed for testing assembly. + "System.Reactive.Providers", + "System.Reactive.Runtime.Remoting", + "System.Reactive.Windows.Forms", + "System.Reactive.Windows.Threading", + "Microsoft.Reactive.Testing", + "Tests.System.Reactive", + }; + +var blacklist = new string [] { + // FIXME: this is the only source that we cannot build. + //Test/../../../../external/rx/Rx.NET/Tests.System.Reactive/Tests/ObservableExTest.cs(1478,27): error CS0411: The type arguments for method `System.Reactive.Linq.ObservableEx.ManySelect(this System.IObservable, System.Func,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly + "ObservableExTest.cs", + + // WPF Dispatcher.Invoke() is not implemented. + "DispatcherSchedulerTest.cs", + // This is not limited to Dispatcher, but many of them are relevant to it, or Winforms (we filter it out by not defining HAS_WINFORMS) + "ObservableConcurrencyTest.cs", + }; + +foreach (var ass in asses) { + + var monoass = ass == "Microsoft.Reactive.Testing" ? + "Mono.Reactive.Testing" : ass; + var basePath = "../../external/rx/Rx.NET"; + var csproj = Path.Combine (basePath, ass, ass + ".csproj"); + var pathPrefix = ass == "Tests.System.Reactive" ? "../../" : "../"; + + // tests are built under Mono.Reactive.Testing directory. + var sources = + monoass == "Tests.System.Reactive" ? + Path.Combine ("Mono.Reactive.Testing", "Mono.Reactive.Testing_test.dll.sources") : + Path.Combine (monoass, monoass + ".dll.sources"); + + var doc = XDocument.Load (csproj); + var rootNS = doc.XPathSelectElement ("//*[local-name()='RootNamespace']").Value; + using (var tw = File.CreateText (sources)) { + foreach (var path in doc.XPathSelectElements ("//*[local-name()='Compile']") + .Select (el => el.Attribute ("Include").Value) + .Select (s => s.Replace ("\\", "/"))) + if (!blacklist.Any (b => path.Contains (b))) + tw.WriteLine (Path.Combine (pathPrefix, basePath, ass, path)); + } + + var argsPath = Path.Combine (Path.GetDirectoryName (sources), "more_build_args"); + using (var tw = File.CreateText (argsPath)) { + tw.WriteLine ("-d:SIGNED"); + tw.WriteLine ("-delaysign"); + tw.WriteLine ("-keyfile:../reactive.pub"); + + foreach (var path in doc.XPathSelectElements ("//*[local-name()='EmbeddedResource']")) { + var res = path.Attribute ("Include").Value; + var resx = Path.Combine (basePath, ass, res); + var resFileName = res.Replace ("resx", "resources"); + var resxDest = Path.Combine (monoass, res); + var resPath = Path.Combine (monoass, resFileName); + if (File.Exists (resxDest)) + File.Delete (resxDest); + File.Copy (resx, resxDest); + //Process.Start ("resgen", String.Format ("{0} {1}", resx, resPath)); + tw.WriteLine ("-resource:{0},{1}.{2}", resFileName, rootNS, resFileName); + } + } +} + diff --git a/mcs/class/corlib/Documentation/en/System/Action.xml b/mcs/class/corlib/Documentation/en/System/Action.xml deleted file mode 100644 index 724af185244..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Action.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - System.Void - - - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Action`1.xml b/mcs/class/corlib/Documentation/en/System/Action`1.xml deleted file mode 100644 index accc1e86af5..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Action`1.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - mscorlib - 2.0.0.0 - 4.0.0.0 - - - - - Contravariant - - - - - System.Delegate - - - - - - System.Void - - - The type. - The object on which to perform an action. - A delegate to a method that returns no values, and takes one parameter. - Since the compiler can infer the types, you do not need to provide the type, this is typically used with the method or the 's ForEach method. - - -// -// Simple "echo" implementation -// -using System; - -class X { - - static void Main (string [] args) - { - Array.ForEach (args, print); - Console.WriteLine (); - } - - static void print (string a) - { - Console.Write (a); - Console.Write (" "); - } -} - - - - diff --git a/mcs/class/corlib/Documentation/en/System/Action`2.xml b/mcs/class/corlib/Documentation/en/System/Action`2.xml deleted file mode 100644 index 8241ea6fce6..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Action`2.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - System.Void - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Action`3.xml b/mcs/class/corlib/Documentation/en/System/Action`3.xml deleted file mode 100644 index b535b47454f..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Action`3.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - - System.Void - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Action`4.xml b/mcs/class/corlib/Documentation/en/System/Action`4.xml deleted file mode 100644 index 0c0ba7b755d..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Action`4.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - - - System.Void - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Func`1.xml b/mcs/class/corlib/Documentation/en/System/Func`1.xml deleted file mode 100644 index a83dfa21729..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Func`1.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Covariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - TResult - - - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Func`2.xml b/mcs/class/corlib/Documentation/en/System/Func`2.xml deleted file mode 100644 index 54d8e04a597..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Func`2.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Covariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - TResult - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Func`3.xml b/mcs/class/corlib/Documentation/en/System/Func`3.xml deleted file mode 100644 index 98b1f6b0eda..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Func`3.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - Covariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - TResult - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Func`4.xml b/mcs/class/corlib/Documentation/en/System/Func`4.xml deleted file mode 100644 index e230df7b2da..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Func`4.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - Covariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - - TResult - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/Func`5.xml b/mcs/class/corlib/Documentation/en/System/Func`5.xml deleted file mode 100644 index dcba2aad60a..00000000000 --- a/mcs/class/corlib/Documentation/en/System/Func`5.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - Contravariant - - - - - Covariant - - - - - System.Delegate - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - - - - - - - TResult - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - diff --git a/mcs/class/corlib/Documentation/en/System/InvalidTimeZoneException.xml b/mcs/class/corlib/Documentation/en/System/InvalidTimeZoneException.xml deleted file mode 100644 index f3783b556bb..00000000000 --- a/mcs/class/corlib/Documentation/en/System/InvalidTimeZoneException.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.Exception - - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - To be added. - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - diff --git a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+AdjustmentRule.xml b/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+AdjustmentRule.xml deleted file mode 100644 index 03cdb17b9de..00000000000 --- a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+AdjustmentRule.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.Object - - - - System.IEquatable<System.TimeZoneInfo+AdjustmentRule> - - - System.Runtime.Serialization.IDeserializationCallback - - - System.Runtime.Serialization.ISerializable - - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo+AdjustmentRule - - - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.DateTime - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.DateTime - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeSpan - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeZoneInfo+TransitionTime - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeZoneInfo+TransitionTime - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Int32 - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - diff --git a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+TransitionTime.xml b/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+TransitionTime.xml deleted file mode 100644 index 677456ca52e..00000000000 --- a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo+TransitionTime.xml +++ /dev/null @@ -1,304 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.ValueType - - - - System.IEquatable<System.TimeZoneInfo+TransitionTime> - - - System.Runtime.Serialization.IDeserializationCallback - - - System.Runtime.Serialization.ISerializable - - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo+TransitionTime - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo+TransitionTime - - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.Int32 - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.DayOfWeek - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Int32 - - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.Boolean - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.Int32 - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.DateTime - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.Int32 - - - To be added. - To be added. - To be added. - - - - diff --git a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo.xml b/mcs/class/corlib/Documentation/en/System/TimeZoneInfo.xml deleted file mode 100644 index 1fdf45cdcb6..00000000000 --- a/mcs/class/corlib/Documentation/en/System/TimeZoneInfo.xml +++ /dev/null @@ -1,808 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.Object - - - - System.IEquatable<System.TimeZoneInfo> - - - System.Runtime.Serialization.IDeserializationCallback - - - System.Runtime.Serialization.ISerializable - - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeSpan - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTimeOffset - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTimeOffset - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.DateTime - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo - - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo - - - - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo - - - - - - - - - - - - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.String - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.String - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeZoneInfo+AdjustmentRule[] - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeSpan[] - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeSpan[] - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Int32 - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Collections.ObjectModel.ReadOnlyCollection<System.TimeZoneInfo> - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeSpan - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.TimeSpan - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.String - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Boolean - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeZoneInfo - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.String - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.Boolean - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.Void - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.String - - - - To be added. - To be added. - To be added. - - - - - Method - - 4.0.0.0 - - - System.String - - - - To be added. - To be added. - To be added. - - - - - Property - - 4.0.0.0 - - - System.TimeZoneInfo - - - To be added. - To be added. - To be added. - - - - diff --git a/mcs/class/corlib/Documentation/en/System/TimeZoneNotFoundException.xml b/mcs/class/corlib/Documentation/en/System/TimeZoneNotFoundException.xml deleted file mode 100644 index 975fe7fe35e..00000000000 --- a/mcs/class/corlib/Documentation/en/System/TimeZoneNotFoundException.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - mscorlib - 4.0.0.0 - - - System.Exception - - - - - System.Runtime.CompilerServices.TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") - - - - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - To be added. - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - - Constructor - - 4.0.0.0 - - - - - - - To be added. - To be added. - To be added. - To be added. - - - - diff --git a/mcs/class/corlib/Mono.Interop/ComInteropProxy.cs b/mcs/class/corlib/Mono.Interop/ComInteropProxy.cs index 6f6c04cbbf8..b97f416a83d 100644 --- a/mcs/class/corlib/Mono.Interop/ComInteropProxy.cs +++ b/mcs/class/corlib/Mono.Interop/ComInteropProxy.cs @@ -27,7 +27,7 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // - +#if !FULL_AOT_RUNTIME using System; using System.Collections; using System.Reflection; @@ -153,3 +153,4 @@ namespace Mono.Interop } } } +#endif diff --git a/mcs/class/corlib/Mono.Interop/IDispatch.cs b/mcs/class/corlib/Mono.Interop/IDispatch.cs index 4d42f162936..4c7dced4bfb 100644 --- a/mcs/class/corlib/Mono.Interop/IDispatch.cs +++ b/mcs/class/corlib/Mono.Interop/IDispatch.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Runtime.InteropServices; @@ -39,3 +40,4 @@ namespace Mono.Interop { } } +#endif diff --git a/mcs/class/corlib/Mono.Interop/IUnknown.cs b/mcs/class/corlib/Mono.Interop/IUnknown.cs index 197058974f8..0755113912f 100644 --- a/mcs/class/corlib/Mono.Interop/IUnknown.cs +++ b/mcs/class/corlib/Mono.Interop/IUnknown.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Runtime.InteropServices; @@ -39,3 +40,4 @@ namespace Mono.Interop { } } +#endif diff --git a/mcs/class/corlib/Mono/DataConverter.cs b/mcs/class/corlib/Mono/DataConverter.cs index 54600853272..8dfdbd16567 100644 --- a/mcs/class/corlib/Mono/DataConverter.cs +++ b/mcs/class/corlib/Mono/DataConverter.cs @@ -45,16 +45,15 @@ using System.Text; namespace Mono { #if MONO_DATACONVERTER_PUBLIC - unsafe public abstract class DataConverter { -#else - unsafe internal abstract class DataConverter { + public +#endif + unsafe abstract class DataConverter { // Disables the warning: CLS compliance checking will not be performed on // `XXXX' because it is not visible from outside this assembly #pragma warning disable 3019 -#endif - static DataConverter SwapConv = new SwapConverter (); - static DataConverter CopyConv = new CopyConverter (); + static readonly DataConverter SwapConv = new SwapConverter (); + static readonly DataConverter CopyConv = new CopyConverter (); public static readonly bool IsLittleEndian = BitConverter.IsLittleEndian; diff --git a/mcs/class/corlib/System.Diagnostics/Debugger.cs b/mcs/class/corlib/System.Diagnostics/Debugger.cs index 02113358021..d7b3544dfe5 100644 --- a/mcs/class/corlib/System.Diagnostics/Debugger.cs +++ b/mcs/class/corlib/System.Diagnostics/Debugger.cs @@ -110,5 +110,15 @@ namespace System.Diagnostics public Debugger() { } + +#if MONODROID + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private extern static void Mono_UnhandledException_internal (Exception ex); + + internal static void Mono_UnhandledException (Exception ex) + { + Mono_UnhandledException_internal (ex); + } +#endif } } diff --git a/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs index 5493215a529..0b0da05f27e 100644 --- a/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Resources; @@ -1197,3 +1198,4 @@ namespace System.Reflection.Emit #endif } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs b/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs index 68ed8819965..1aceb94ef07 100644 --- a/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs +++ b/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit @@ -45,3 +46,4 @@ namespace System.Reflection.Emit #endif } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ConstructorBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/ConstructorBuilder.cs index 88a27676b7c..2391dc8be2c 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ConstructorBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ConstructorBuilder.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -411,3 +412,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ConstructorOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/ConstructorOnTypeBuilderInst.cs index 9b29c058dac..ea3cee589d0 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ConstructorOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ConstructorOnTypeBuilderInst.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Globalization; using System.Reflection; @@ -192,3 +193,4 @@ namespace System.Reflection.Emit } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs index d389617c5bc..862420a6cc0 100644 --- a/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -535,3 +536,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/DerivedTypes.cs b/mcs/class/corlib/System.Reflection.Emit/DerivedTypes.cs index eca84939f88..4d8b2ee34ba 100644 --- a/mcs/class/corlib/System.Reflection.Emit/DerivedTypes.cs +++ b/mcs/class/corlib/System.Reflection.Emit/DerivedTypes.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; using System.Reflection.Emit; using System.Collections; @@ -460,3 +461,4 @@ namespace System.Reflection.Emit } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/DynamicILInfo.cs b/mcs/class/corlib/System.Reflection.Emit/DynamicILInfo.cs index 17551e3874c..c086c63bd15 100644 --- a/mcs/class/corlib/System.Reflection.Emit/DynamicILInfo.cs +++ b/mcs/class/corlib/System.Reflection.Emit/DynamicILInfo.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Runtime.InteropServices; @@ -129,3 +130,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs b/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs index 5378f7e2a01..931573d5449 100644 --- a/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs +++ b/mcs/class/corlib/System.Reflection.Emit/DynamicMethod.cs @@ -31,6 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; @@ -450,3 +451,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/EnumBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/EnumBuilder.cs index 2d0c5249701..50a67447377 100644 --- a/mcs/class/corlib/System.Reflection.Emit/EnumBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/EnumBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -419,3 +420,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/EventBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/EventBuilder.cs index 457e343b9e3..2393e2abc9b 100644 --- a/mcs/class/corlib/System.Reflection.Emit/EventBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/EventBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -161,3 +162,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/EventOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/EventOnTypeBuilderInst.cs index 32e95749392..2e4367ab965 100644 --- a/mcs/class/corlib/System.Reflection.Emit/EventOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/EventOnTypeBuilderInst.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Collections; using System.Globalization; @@ -129,3 +130,4 @@ namespace System.Reflection.Emit } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/EventToken.cs b/mcs/class/corlib/System.Reflection.Emit/EventToken.cs index 6d04142bc52..912aa16abb5 100644 --- a/mcs/class/corlib/System.Reflection.Emit/EventToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/EventToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -100,3 +101,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/FieldBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/FieldBuilder.cs index 466f50259b5..053d8c831e4 100644 --- a/mcs/class/corlib/System.Reflection.Emit/FieldBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/FieldBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001-2002 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -208,12 +209,6 @@ namespace System.Reflection.Emit { throw CreateNotSupportedException (); } - internal override UnmanagedMarshal UMarshal { - get { - return marshal_info; - } - } - private Exception CreateNotSupportedException () { return new NotSupportedException ("The invoked member is not supported in a dynamic module."); @@ -253,3 +248,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/FieldOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/FieldOnTypeBuilderInst.cs index c431bad1e9c..ca3d43d85f9 100644 --- a/mcs/class/corlib/System.Reflection.Emit/FieldOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/FieldOnTypeBuilderInst.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Globalization; using System.Reflection; @@ -128,3 +129,4 @@ namespace System.Reflection.Emit } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/FieldToken.cs b/mcs/class/corlib/System.Reflection.Emit/FieldToken.cs index 85cc6599ee6..7c7135ee172 100644 --- a/mcs/class/corlib/System.Reflection.Emit/FieldToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/FieldToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -99,3 +100,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs b/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs index 55795aa4478..0a7a464b768 100644 --- a/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs +++ b/mcs/class/corlib/System.Reflection.Emit/FlowControl.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -87,3 +88,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/GenericTypeParameterBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/GenericTypeParameterBuilder.cs index 7f51aea6a38..696ec9cef3a 100644 --- a/mcs/class/corlib/System.Reflection.Emit/GenericTypeParameterBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/GenericTypeParameterBuilder.cs @@ -29,6 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; using System.Reflection.Emit; using System.Collections; @@ -456,3 +457,4 @@ namespace System.Reflection.Emit } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs b/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs index cd521f59a38..cc039c54d9c 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Collections; using System.Diagnostics.SymbolStore; @@ -1156,3 +1157,4 @@ namespace System.Reflection.Emit { public int EndCol; } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/Label.cs b/mcs/class/corlib/System.Reflection.Emit/Label.cs index 4834aa2cf2d..94d35f80f51 100644 --- a/mcs/class/corlib/System.Reflection.Emit/Label.cs +++ b/mcs/class/corlib/System.Reflection.Emit/Label.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -72,3 +73,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/LocalBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/LocalBuilder.cs index 87a72256aa5..98c9addf504 100644 --- a/mcs/class/corlib/System.Reflection.Emit/LocalBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/LocalBuilder.cs @@ -33,6 +33,7 @@ // (C) 2001, 2002 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -129,3 +130,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs index 11644739c0b..ef727b615de 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodBuilder.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -679,3 +680,4 @@ namespace System.Reflection.Emit #endif } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs index 6f37b59ce18..aa19ecef3bf 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodOnTypeBuilderInst.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Globalization; using System.Reflection; @@ -279,3 +280,4 @@ namespace System.Reflection.Emit } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodRental.cs b/mcs/class/corlib/System.Reflection.Emit/MethodRental.cs index 2aeb1eedb73..b4bc0478522 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodRental.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodRental.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Security.Permissions; using System.Runtime.InteropServices; @@ -81,3 +82,4 @@ namespace System.Reflection.Emit } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MethodToken.cs b/mcs/class/corlib/System.Reflection.Emit/MethodToken.cs index f4ad83a767a..2ccff2a919b 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MethodToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MethodToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -98,3 +99,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs index 9548789299d..76524c6ab1d 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ModuleBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Collections; @@ -994,3 +995,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/MonoArrayMethod.cs b/mcs/class/corlib/System.Reflection.Emit/MonoArrayMethod.cs index 02c334dc5a0..dc9ca4073ee 100644 --- a/mcs/class/corlib/System.Reflection.Emit/MonoArrayMethod.cs +++ b/mcs/class/corlib/System.Reflection.Emit/MonoArrayMethod.cs @@ -31,6 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Globalization; using System.Runtime.CompilerServices; @@ -146,3 +147,4 @@ namespace System.Reflection { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCode.cs b/mcs/class/corlib/System.Reflection.Emit/OpCode.cs index e85c58f7009..81edbd5b5ad 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCode.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCode.cs @@ -26,6 +26,7 @@ // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -152,3 +153,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs index 67ddad4a581..bcac4a31c1d 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodeNames.cs @@ -1,3 +1,4 @@ +#if !FULL_AOT_RUNTIME namespace System.Reflection.Emit { static class OpCodeNames { internal static readonly string [] names = { @@ -308,3 +309,4 @@ namespace System.Reflection.Emit { }; } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs index c50e574bde8..681ea6e4ff5 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodeType.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -74,3 +75,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs b/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs index 03317d2626f..840ee183ffc 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OpCodes.cs @@ -1,3 +1,4 @@ +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -928,3 +929,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/OperandType.cs b/mcs/class/corlib/System.Reflection.Emit/OperandType.cs index f7c5d0a7dc5..c8f785d0d3d 100644 --- a/mcs/class/corlib/System.Reflection.Emit/OperandType.cs +++ b/mcs/class/corlib/System.Reflection.Emit/OperandType.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -112,3 +113,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PEFileKinds.cs b/mcs/class/corlib/System.Reflection.Emit/PEFileKinds.cs index f28340e0e24..4cf610fab35 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PEFileKinds.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PEFileKinds.cs @@ -22,6 +22,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -35,3 +36,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs b/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs index f3db05c67ba..08052a3386e 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PackingSize.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -71,3 +72,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ParameterBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/ParameterBuilder.cs index a6a246d1074..97f99805130 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ParameterBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ParameterBuilder.cs @@ -32,6 +32,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -175,3 +176,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/ParameterToken.cs b/mcs/class/corlib/System.Reflection.Emit/ParameterToken.cs index 87f56282a29..9c42bb136f8 100644 --- a/mcs/class/corlib/System.Reflection.Emit/ParameterToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/ParameterToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -98,3 +99,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PropertyBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/PropertyBuilder.cs index 058930c9f9f..8e53d04614f 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PropertyBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PropertyBuilder.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -204,3 +205,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PropertyOnTypeBuilderInst.cs b/mcs/class/corlib/System.Reflection.Emit/PropertyOnTypeBuilderInst.cs index 3d401a1b7a7..578cf06a5d1 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PropertyOnTypeBuilderInst.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PropertyOnTypeBuilderInst.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Globalization; using System.Reflection; @@ -158,3 +159,4 @@ namespace System.Reflection.Emit } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/PropertyToken.cs b/mcs/class/corlib/System.Reflection.Emit/PropertyToken.cs index ca4868ec3ca..e1f2c846965 100644 --- a/mcs/class/corlib/System.Reflection.Emit/PropertyToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/PropertyToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -98,3 +99,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/SignatureHelper.cs b/mcs/class/corlib/System.Reflection.Emit/SignatureHelper.cs index 00a3f366807..d56f96256c0 100644 --- a/mcs/class/corlib/System.Reflection.Emit/SignatureHelper.cs +++ b/mcs/class/corlib/System.Reflection.Emit/SignatureHelper.cs @@ -31,6 +31,7 @@ // (C) 2001 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -430,3 +431,4 @@ namespace System.Reflection.Emit { } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/SignatureToken.cs b/mcs/class/corlib/System.Reflection.Emit/SignatureToken.cs index 193feb610ec..9c6e32ee7b2 100644 --- a/mcs/class/corlib/System.Reflection.Emit/SignatureToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/SignatureToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -97,3 +98,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs b/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs index 524ea8d3059..689197c919c 100644 --- a/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs +++ b/mcs/class/corlib/System.Reflection.Emit/StackBehaviour.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -152,3 +153,4 @@ namespace System.Reflection.Emit { } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/StringToken.cs b/mcs/class/corlib/System.Reflection.Emit/StringToken.cs index 2bba43467ff..ece7c0c6210 100644 --- a/mcs/class/corlib/System.Reflection.Emit/StringToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/StringToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -96,3 +97,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs index fc60d1a377a..462717057cc 100644 --- a/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs @@ -31,6 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Text; using System.Reflection; @@ -1928,3 +1929,4 @@ namespace System.Reflection.Emit } } } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/TypeToken.cs b/mcs/class/corlib/System.Reflection.Emit/TypeToken.cs index 4a8a56b1d9e..9a8970e9cf1 100644 --- a/mcs/class/corlib/System.Reflection.Emit/TypeToken.cs +++ b/mcs/class/corlib/System.Reflection.Emit/TypeToken.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices; namespace System.Reflection.Emit { @@ -98,3 +99,4 @@ namespace System.Reflection.Emit { } +#endif diff --git a/mcs/class/corlib/System.Reflection.Emit/UnmanagedMarshal.cs b/mcs/class/corlib/System.Reflection.Emit/UnmanagedMarshal.cs index b9ed853e902..7cf8c8a5717 100644 --- a/mcs/class/corlib/System.Reflection.Emit/UnmanagedMarshal.cs +++ b/mcs/class/corlib/System.Reflection.Emit/UnmanagedMarshal.cs @@ -31,6 +31,7 @@ // (C) 2001-2002 Ximian, Inc. http://www.ximian.com // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; using System.Runtime.InteropServices; using System; @@ -126,22 +127,6 @@ namespace System.Reflection.Emit { return res; } - - internal MarshalAsAttribute ToMarshalAsAttribute () { - MarshalAsAttribute attr = new MarshalAsAttribute (t); - attr.ArraySubType = tbase; - attr.MarshalCookie = mcookie; - attr.MarshalType = marshaltype; - attr.MarshalTypeRef = marshaltyperef; - if (count == -1) - attr.SizeConst = 0; - else - attr.SizeConst = count; - if (param_num == -1) - attr.SizeParamIndex = 0; - else - attr.SizeParamIndex = (short)param_num; - return attr; - } } } +#endif diff --git a/mcs/class/corlib/System.Reflection/AssemblyName.cs b/mcs/class/corlib/System.Reflection/AssemblyName.cs index 8e96227d2d2..f49c70a8474 100644 --- a/mcs/class/corlib/System.Reflection/AssemblyName.cs +++ b/mcs/class/corlib/System.Reflection/AssemblyName.cs @@ -248,6 +248,9 @@ namespace System.Reflection { private bool IsPublicKeyValid { get { +#if FULL_AOT_RUNTIME + return true; +#else // check for ECMA key if (publicKey.Length == 16) { int i = 0; @@ -281,6 +284,7 @@ namespace System.Reflection { } return false; +#endif } } @@ -303,6 +307,9 @@ namespace System.Reflection { private byte [] ComputePublicKeyToken () { +#if FULL_AOT_RUNTIME + return new byte [0]; +#else HashAlgorithm ha = SHA1.Create (); byte [] hash = ha.ComputeHash (publicKey); // we need the last 8 bytes in reverse order @@ -310,6 +317,7 @@ namespace System.Reflection { Array.Copy (hash, (hash.Length - 8), token, 0, 8); Array.Reverse (token, 0, 8); return token; +#endif } [MonoTODO] diff --git a/mcs/class/corlib/System.Reflection/Binder.cs b/mcs/class/corlib/System.Reflection/Binder.cs index 3bb636451ed..295b2960138 100644 --- a/mcs/class/corlib/System.Reflection/Binder.cs +++ b/mcs/class/corlib/System.Reflection/Binder.cs @@ -555,6 +555,7 @@ namespace System.Reflection var requiredType = methodArgs [j].ParameterType; if (types [j] == requiredType) continue; +#if !MOBILE if (types [j] == typeof (__ComObject) && requiredType.IsInterface) { var iface = Marshal.GetComInterfaceForObject (parameters [j], requiredType); if (iface != IntPtr.Zero) { @@ -563,6 +564,7 @@ namespace System.Reflection continue; } } +#endif break; } diff --git a/mcs/class/corlib/System.Reflection/EventInfo.cs b/mcs/class/corlib/System.Reflection/EventInfo.cs index 7d82fdcb818..61267f9cfd1 100644 --- a/mcs/class/corlib/System.Reflection/EventInfo.cs +++ b/mcs/class/corlib/System.Reflection/EventInfo.cs @@ -84,6 +84,16 @@ namespace System.Reflection { #endif void AddEventHandler (object target, Delegate handler) { +// this optimization cause problems with full AOT +// see bug https://bugzilla.xamarin.com/show_bug.cgi?id=3682 +#if FULL_AOT_RUNTIME + MethodInfo add = GetAddMethod (); + if (add == null) + throw new InvalidOperationException ("Cannot add a handler to an event that doesn't have a visible add method"); + if (target == null && !add.IsStatic) + throw new TargetException ("Cannot add a handler to a non static event with a null target"); + add.Invoke (target, new object [] {handler}); +#else if (cached_add_event == null) { MethodInfo add = GetAddMethod (); if (add == null) @@ -99,6 +109,7 @@ namespace System.Reflection { //if (target == null && is_instance) // throw new TargetException ("Cannot add a handler to a non static event with a null target"); cached_add_event (target, handler); +#endif } public MethodInfo GetAddMethod() { @@ -187,7 +198,13 @@ namespace System.Reflection { { throw new NotImplementedException (); } + delegate void AddEventAdapter (object _this, Delegate dele); + +// this optimization cause problems with full AOT +// see bug https://bugzilla.xamarin.com/show_bug.cgi?id=3682 +// do not revove the above delegate or it's field since it's required by the runtime! +#if !FULL_AOT_RUNTIME delegate void AddEvent (T _this, D dele); delegate void StaticAddEvent (D dele); @@ -246,5 +263,6 @@ namespace System.Reflection { adapterFrame = adapterFrame.MakeGenericMethod (typeVector); return (AddEventAdapter)Delegate.CreateDelegate (typeof (AddEventAdapter), addHandlerDelegate, adapterFrame, true); } +#endif } } diff --git a/mcs/class/corlib/System.Reflection/FieldInfo.cs b/mcs/class/corlib/System.Reflection/FieldInfo.cs index aba3e99969e..93ac75de4af 100644 --- a/mcs/class/corlib/System.Reflection/FieldInfo.cs +++ b/mcs/class/corlib/System.Reflection/FieldInfo.cs @@ -28,7 +28,6 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System.Diagnostics; -using System.Reflection.Emit; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -191,13 +190,7 @@ namespace System.Reflection { } [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern UnmanagedMarshal GetUnmanagedMarshal (); - - internal virtual UnmanagedMarshal UMarshal { - get { - return GetUnmanagedMarshal (); - } - } + private extern MarshalAsAttribute get_marshal_info (); internal object[] GetPseudoCustomAttributes () { @@ -209,7 +202,7 @@ namespace System.Reflection { if (DeclaringType.IsExplicitLayout) count ++; - UnmanagedMarshal marshalAs = UMarshal; + MarshalAsAttribute marshalAs = get_marshal_info (); if (marshalAs != null) count ++; @@ -223,7 +216,7 @@ namespace System.Reflection { if (DeclaringType.IsExplicitLayout) attrs [count ++] = new FieldOffsetAttribute (GetFieldOffset ()); if (marshalAs != null) - attrs [count ++] = marshalAs.ToMarshalAsAttribute (); + attrs [count ++] = marshalAs; return attrs; } diff --git a/mcs/class/corlib/System.Reflection/MethodBase.cs b/mcs/class/corlib/System.Reflection/MethodBase.cs index b03c97bead8..1f62fe62fde 100644 --- a/mcs/class/corlib/System.Reflection/MethodBase.cs +++ b/mcs/class/corlib/System.Reflection/MethodBase.cs @@ -30,7 +30,9 @@ using System.Diagnostics; using System.Globalization; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -181,6 +183,7 @@ namespace System.Reflection { } internal virtual int get_next_table_index (object obj, int table, bool inc) { +#if !FULL_AOT_RUNTIME if (this is MethodBuilder) { MethodBuilder mb = (MethodBuilder)this; return mb.get_next_table_index (obj, table, inc); @@ -189,6 +192,7 @@ namespace System.Reflection { ConstructorBuilder mb = (ConstructorBuilder)this; return mb.get_next_table_index (obj, table, inc); } +#endif throw new Exception ("Method is not a builder method"); } diff --git a/mcs/class/corlib/System.Reflection/MonoAssembly.cs b/mcs/class/corlib/System.Reflection/MonoAssembly.cs index 8bfead75816..b861da70e00 100644 --- a/mcs/class/corlib/System.Reflection/MonoAssembly.cs +++ b/mcs/class/corlib/System.Reflection/MonoAssembly.cs @@ -30,7 +30,9 @@ using System; using System.Collections; using System.Globalization; using System.Runtime.InteropServices; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Collections.Generic; namespace System.Reflection { @@ -57,7 +59,7 @@ namespace System.Reflection { throw new ArgumentException ("name", "Name cannot be empty"); res = InternalGetType (null, name, throwOnError, ignoreCase); -#if !(NET_4_0 || MOONLIGHT || MOBILE) +#if !(NET_4_0 || MOONLIGHT || MOBILE) && !FULL_AOT_RUNTIME if (res is TypeBuilder) { if (throwOnError) throw new TypeLoadException (string.Format ("Could not load type '{0}' from assembly '{1}'", name, this)); diff --git a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs index 9e6d28c61a9..ad5e9436fee 100644 --- a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs +++ b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs @@ -31,6 +31,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; using System.Reflection.Emit; using System.Collections; @@ -510,3 +511,4 @@ namespace System.Reflection } } +#endif diff --git a/mcs/class/corlib/System.Reflection/MonoMethod.cs b/mcs/class/corlib/System.Reflection/MonoMethod.cs index 234acd90a0d..79d9e15a18d 100644 --- a/mcs/class/corlib/System.Reflection/MonoMethod.cs +++ b/mcs/class/corlib/System.Reflection/MonoMethod.cs @@ -34,7 +34,9 @@ using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Security; using System.Threading; using System.Text; @@ -99,7 +101,7 @@ namespace System.Reflection { } [MethodImplAttribute(MethodImplOptions.InternalCall)] - static extern UnmanagedMarshal get_retval_marshal (IntPtr handle); + static extern MarshalAsAttribute get_retval_marshal (IntPtr handle); static internal ParameterInfo GetReturnParameterInfo (MonoMethod method) { @@ -392,8 +394,10 @@ namespace System.Reflection { hasUserType = true; } +#if !FULL_AOT_RUNTIME if (hasUserType) return new MethodOnTypeBuilderInst (this, methodInstantiation); +#endif MethodInfo ret = MakeGenericMethod_impl (methodInstantiation); if (ret == null) diff --git a/mcs/class/corlib/System.Reflection/ParameterInfo.cs b/mcs/class/corlib/System.Reflection/ParameterInfo.cs index 7ea808b8639..e072223b36e 100644 --- a/mcs/class/corlib/System.Reflection/ParameterInfo.cs +++ b/mcs/class/corlib/System.Reflection/ParameterInfo.cs @@ -25,7 +25,9 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Collections.Generic; @@ -45,12 +47,12 @@ namespace System.Reflection protected string NameImpl; protected int PositionImpl; protected ParameterAttributes AttrsImpl; - private UnmanagedMarshal marshalAs; - //ParameterInfo parent; + private MarshalAsAttribute marshalAs; protected ParameterInfo () { } +#if !FULL_AOT_RUNTIME internal ParameterInfo (ParameterBuilder pb, Type type, MemberInfo member, int position) { this.ClassImpl = type; this.MemberImpl = member; @@ -64,6 +66,7 @@ namespace System.Reflection this.AttrsImpl = ParameterAttributes.None; } } +#endif /*FIXME this constructor looks very broken in the position parameter*/ internal ParameterInfo (ParameterInfo pinfo, Type type, MemberInfo member, int position) { @@ -90,7 +93,7 @@ namespace System.Reflection } /* to build a ParameterInfo for the return type of a method */ - internal ParameterInfo (Type type, MemberInfo member, UnmanagedMarshal marshalAs) { + internal ParameterInfo (Type type, MemberInfo member, MarshalAsAttribute marshalAs) { this.ClassImpl = type; this.MemberImpl = member; this.NameImpl = ""; @@ -244,7 +247,7 @@ namespace System.Reflection attrs [count ++] = new OutAttribute (); if (marshalAs != null) - attrs [count ++] = marshalAs.ToMarshalAsAttribute (); + attrs [count ++] = marshalAs.Copy (); return attrs; } diff --git a/mcs/class/corlib/System.Runtime.InteropServices.ComTypes/EXCEPINFO.cs b/mcs/class/corlib/System.Runtime.InteropServices.ComTypes/EXCEPINFO.cs index d9f68bb4e6d..d30f264b393 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices.ComTypes/EXCEPINFO.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices.ComTypes/EXCEPINFO.cs @@ -30,6 +30,7 @@ // (C) 2002 Ximian, Inc. using System; +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices.ComTypes { [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)] @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices.ComTypes public int scode; } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/DispatchWrapper.cs b/mcs/class/corlib/System.Runtime.InteropServices/DispatchWrapper.cs index a20ba838fee..dfc5a2a29f2 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/DispatchWrapper.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/DispatchWrapper.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices @@ -49,3 +50,4 @@ namespace System.Runtime.InteropServices } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/EXCEPINFO.cs b/mcs/class/corlib/System.Runtime.InteropServices/EXCEPINFO.cs index f3d4b8b6bfb..0e61c36b7fd 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/EXCEPINFO.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/EXCEPINFO.cs @@ -30,6 +30,7 @@ using System; +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -49,3 +50,4 @@ namespace System.Runtime.InteropServices } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ErrorWrapper.cs b/mcs/class/corlib/System.Runtime.InteropServices/ErrorWrapper.cs index 0588b940bb5..4bf947af4bc 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ErrorWrapper.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ErrorWrapper.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices @@ -60,3 +61,4 @@ namespace System.Runtime.InteropServices } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibConverter.cs b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibConverter.cs index 487c890f088..1e335ba7c1c 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibConverter.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibConverter.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; using System.Reflection.Emit; @@ -46,3 +47,4 @@ namespace System.Runtime.InteropServices { bool GetPrimaryInteropAssembly (Guid g, int major, int minor, int lcid, out string asmName, out string asmCodeBase); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNameProvider.cs b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNameProvider.cs index 6e87d5902f3..8dc67cd2626 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNameProvider.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNameProvider.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [ComVisible (true)] @@ -41,3 +42,4 @@ namespace System.Runtime.InteropServices { } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNotifySink.cs b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNotifySink.cs index c7983560e77..b8ee0fedf17 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNotifySink.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibExporterNotifySink.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; namespace System.Runtime.InteropServices { @@ -42,3 +43,4 @@ namespace System.Runtime.InteropServices { object ResolveRef (Assembly assembly); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibImporterNotifySink.cs b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibImporterNotifySink.cs index 832992c8a58..a51817b7320 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibImporterNotifySink.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ITypeLibImporterNotifySink.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection; namespace System.Runtime.InteropServices { @@ -41,3 +42,4 @@ namespace System.Runtime.InteropServices { Assembly ResolveRef([MarshalAs(UnmanagedType.Interface)] object typeLib); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ImportedFromTypeLibAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/ImportedFromTypeLibAttribute.cs index 933a535514c..2a26c783959 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/ImportedFromTypeLibAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/ImportedFromTypeLibAttribute.cs @@ -29,6 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs b/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs index 1e9673cb357..4cfb7c2b5eb 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs @@ -40,12 +40,11 @@ using System.Threading; using System.Runtime.ConstrainedExecution; #if !MOONLIGHT +#if !FULL_AOT_RUNTIME using System.Runtime.InteropServices.ComTypes; -#endif - -#if !MOONLIGHT using Mono.Interop; #endif +#endif namespace System.Runtime.InteropServices { @@ -55,14 +54,20 @@ namespace System.Runtime.InteropServices public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is public static readonly int SystemDefaultCharSize = Environment.OSVersion.Platform == PlatformID.Win32NT ? 2 : 1; +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static int AddRefInternal (IntPtr pUnk); +#endif public static int AddRef (IntPtr pUnk) { +#if !MOBILE if (pUnk == IntPtr.Zero) throw new ArgumentException ("Value cannot be null.", "pUnk"); return AddRefInternal (pUnk); +#else + throw new NotImplementedException (); +#endif } [MethodImplAttribute(MethodImplOptions.InternalCall)] @@ -184,7 +189,7 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } -#if !MOONLIGHT +#if !FULL_AOT_RUNTIME && !MOONLIGHT public static object CreateWrapperOfType (object o, Type t) { __ComObject co = o as __ComObject; @@ -267,7 +272,7 @@ namespace System.Runtime.InteropServices FreeHGlobal (s); } -#if !MOONLIGHT +#if !FULL_AOT_RUNTIME && !MOONLIGHT public static Guid GenerateGuidForType (Type type) { return type.GUID; @@ -302,6 +307,7 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static IntPtr GetCCW (object o, Type T); @@ -312,12 +318,17 @@ namespace System.Runtime.InteropServices else return GetCCW (o, T); } +#endif public static IntPtr GetComInterfaceForObject (object o, Type T) { +#if !MOBILE IntPtr pItf = GetComInterfaceForObjectInternal (o, T); AddRef (pItf); return pItf; +#else + throw new NotImplementedException (); +#endif } [MonoTODO] @@ -332,11 +343,14 @@ namespace System.Runtime.InteropServices throw new NotSupportedException ("MSDN states user code should never need to call this method."); } +#if !MOBILE [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static int GetComSlotForMethodInfoInternal (MemberInfo m); +#endif public static int GetComSlotForMethodInfo (MemberInfo m) { +#if !MOBILE if (m == null) throw new ArgumentNullException ("m"); if (!(m is MethodInfo)) @@ -344,6 +358,9 @@ namespace System.Runtime.InteropServices if (!m.DeclaringType.IsInterface) throw new ArgumentException ("The MemberInfo must be an interface method.", "m"); return GetComSlotForMethodInfoInternal (m); +#else + throw new NotImplementedException (); +#endif } [MonoTODO] @@ -372,8 +389,9 @@ namespace System.Runtime.InteropServices return m.GetHINSTANCE (); } -#endif // !NET_2_1 +#endif // !MOONLIGHT +#if !FULL_AOT_RUNTIME [MonoTODO ("SetErrorInfo")] public static int GetHRForException (Exception e) { @@ -447,11 +465,14 @@ namespace System.Runtime.InteropServices Marshal.StructureToPtr(vt, pDstNativeVariant, false); } +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] private static extern object GetObjectForCCW (IntPtr pUnk); +#endif public static object GetObjectForIUnknown (IntPtr pUnk) { +#if !MOBILE object obj = GetObjectForCCW (pUnk); // was not a CCW if (obj == null) { @@ -459,6 +480,9 @@ namespace System.Runtime.InteropServices obj = proxy.GetTransparentProxy (); } return obj; +#else + throw new NotImplementedException (); +#endif } public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant) @@ -510,6 +534,7 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } +#if !FULL_AOT_RUNTIME [Obsolete] [MonoTODO] public static string GetTypeInfoName (UCOMITypeInfo pTI) @@ -577,6 +602,7 @@ namespace System.Runtime.InteropServices { throw new NotImplementedException (); } +#endif [MonoTODO] [Obsolete ("This method has been deprecated")] @@ -585,8 +611,15 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] public extern static bool IsComObject (object o); +#else + public static bool IsComObject (object o) + { + throw new NotImplementedException (); + } +#endif [MonoTODO] public static bool IsTypeVisibleFromCom (Type t) @@ -600,6 +633,7 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } #endif // !NET_2_1 +#endif [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] @@ -638,8 +672,15 @@ namespace System.Runtime.InteropServices [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static string PtrToStringUni (IntPtr ptr, int len); +#if !MOBILE [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static string PtrToStringBSTR (IntPtr ptr); +#else + public static string PtrToStringBSTR (IntPtr ptr) + { + throw new NotImplementedException (); + } +#endif [MethodImplAttribute(MethodImplOptions.InternalCall)] [ComVisible (true)] @@ -649,14 +690,20 @@ namespace System.Runtime.InteropServices [ComVisible (true)] public extern static object PtrToStructure (IntPtr ptr, Type structureType); +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv); +#endif public static int QueryInterface (IntPtr pUnk, ref Guid iid, out IntPtr ppv) { +#if !MOBILE if (pUnk == IntPtr.Zero) throw new ArgumentException ("Value cannot be null.", "pUnk"); return QueryInterfaceInternal (pUnk, ref iid, out ppv); +#else + throw new NotImplementedException (); +#endif } public static byte ReadByte (IntPtr ptr) @@ -747,18 +794,26 @@ namespace System.Runtime.InteropServices [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static IntPtr ReAllocHGlobal (IntPtr pv, IntPtr cb); +#if !MOBILE [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static int ReleaseInternal (IntPtr pUnk); +#endif [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)] public static int Release (IntPtr pUnk) { +#if !MOBILE if (pUnk == IntPtr.Zero) throw new ArgumentException ("Value cannot be null.", "pUnk"); + return ReleaseInternal (pUnk); +#else + throw new NotImplementedException (); +#endif } +#if !FULL_AOT_RUNTIME #if !MOONLIGHT [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static int ReleaseComObjectInternal (object co); @@ -785,6 +840,7 @@ namespace System.Runtime.InteropServices throw new NotSupportedException ("MSDN states user code should never need to call this method."); } #endif // !NET_2_1 +#endif [ComVisible (true)] public static int SizeOf (object structure) @@ -1068,12 +1124,14 @@ namespace System.Runtime.InteropServices return null; } +#if !FULL_AOT_RUNTIME #if !MOONLIGHT public static int FinalReleaseComObject (object o) { while (ReleaseComObject (o) != 0); return 0; } +#endif #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/mcs/class/corlib/System.Runtime.InteropServices/MarshalAsAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/MarshalAsAttribute.cs index 9bb9e9a9257..ac0dc4145bf 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/MarshalAsAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/MarshalAsAttribute.cs @@ -35,25 +35,29 @@ namespace System.Runtime.InteropServices { [ComVisible(true)] [AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited=false)] + [StructLayout (LayoutKind.Sequential)] public sealed class MarshalAsAttribute : Attribute { - private UnmanagedType utype; - public UnmanagedType ArraySubType; + /*keep these fields in sync with object-internals.h*/ +#pragma warning disable 169, 414 public string MarshalCookie; - [ComVisible(true)] public string MarshalType; [ComVisible(true)] public Type MarshalTypeRef; - + public Type SafeArrayUserDefinedSubType; + + private UnmanagedType utype; + public UnmanagedType ArraySubType; #if !MOONLIGHT public VarEnum SafeArraySubType; +#else + private int SafeArraySubType; #endif - public int SizeConst; - public short SizeParamIndex; - public Type SafeArrayUserDefinedSubType; public int IidParameterIndex; + public short SizeParamIndex; +#pragma warning disable 169, 414 public MarshalAsAttribute (short unmanagedType) { utype = (UnmanagedType)unmanagedType; @@ -64,5 +68,10 @@ namespace System.Runtime.InteropServices { public UnmanagedType Value { get {return utype;} } + + internal MarshalAsAttribute Copy () + { + return (MarshalAsAttribute)this.MemberwiseClone (); + } } } diff --git a/mcs/class/corlib/System.Runtime.InteropServices/RegistrationServices.cs b/mcs/class/corlib/System.Runtime.InteropServices/RegistrationServices.cs index d2037138b44..6a246d026a9 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/RegistrationServices.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/RegistrationServices.cs @@ -50,10 +50,9 @@ namespace System.Runtime.InteropServices return guidManagedCategory; } - [MonoTODO ("implement")] public virtual string GetProgIdForType (Type type) { - throw new NotImplementedException (); + return Marshal.GenerateProgIdForType(type); } [MonoTODO ("implement")] diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibConverter.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibConverter.cs index b7ce95e27e0..9cd6736cf8d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibConverter.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibConverter.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.Reflection; using System.Reflection.Emit; @@ -69,3 +70,4 @@ namespace System.Runtime.InteropServices } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibExporterFlags.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibExporterFlags.cs index 39309075351..957e6892f2d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibExporterFlags.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibExporterFlags.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [ComVisible(true)] @@ -43,3 +44,4 @@ namespace System.Runtime.InteropServices ExportAs64Bit = 32 } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncAttribute.cs index 29fcc728997..215efa65d53 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncAttribute.cs @@ -29,6 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices { @@ -54,3 +55,4 @@ namespace System.Runtime.InteropServices { } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncFlags.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncFlags.cs index 6bcabc2b02f..b0dddbdbf3b 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncFlags.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibFuncFlags.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [ComVisible(true)] @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { FImmediateBind = 4096, } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImportClassAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImportClassAttribute.cs index 0921e92e8ee..43eb92a47d5 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImportClassAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImportClassAttribute.cs @@ -30,6 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImporterFlags.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImporterFlags.cs index fc611887c4a..e3a9f1a74c5 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImporterFlags.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibImporterFlags.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices @@ -53,3 +54,4 @@ namespace System.Runtime.InteropServices #endif } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeAttribute.cs index ecdb10692b6..9a8a6a85936 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeAttribute.cs @@ -29,6 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices { @@ -55,3 +56,4 @@ namespace System.Runtime.InteropServices { } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeFlags.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeFlags.cs index d122ff098d8..48e141b15ed 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeFlags.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibTypeFlags.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [ComVisible(true)] [Flags] [Serializable] @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { FReverseBind = 8192, } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarAttribute.cs index c830910dc89..595f9d85fee 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarAttribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarAttribute.cs @@ -29,6 +29,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; namespace System.Runtime.InteropServices { @@ -54,3 +55,4 @@ namespace System.Runtime.InteropServices { } } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarFlags.cs b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarFlags.cs index 3de9cc553ff..09030d77cff 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarFlags.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/TypeLibVarFlags.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [ComVisible(true)] @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { FImmediateBind = 4096, } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIBindCtx.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIBindCtx.cs index c56a2bc96c1..da18ded9121 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIBindCtx.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIBindCtx.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -46,3 +47,4 @@ namespace System.Runtime.InteropServices void RevokeObjectParam ([MarshalAs(UnmanagedType.LPWStr)] string pszKey); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPoint.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPoint.cs index 1e514ab4b72..cd0e84f3fc8 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPoint.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPoint.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -41,3 +42,4 @@ namespace System.Runtime.InteropServices void EnumConnections (out UCOMIEnumConnections ppEnum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPointContainer.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPointContainer.cs index 8b192f0d12a..8011610ab7b 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPointContainer.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIConnectionPointContainer.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -38,3 +39,4 @@ namespace System.Runtime.InteropServices void FindConnectionPoint (ref Guid riid, out UCOMIConnectionPoint ppCP); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnectionPoints.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnectionPoints.cs index cfbebd75791..bb669b78e0d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnectionPoints.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnectionPoints.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -43,3 +44,4 @@ namespace System.Runtime.InteropServices void Clone (out UCOMIEnumConnectionPoints ppenum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnections.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnections.cs index 92ee2ec7afb..abfb10c8182 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnections.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumConnections.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -43,3 +44,4 @@ namespace System.Runtime.InteropServices void Clone (out UCOMIEnumConnections ppenum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumMoniker.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumMoniker.cs index d24fe2d2882..bb0d59519ea 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumMoniker.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumMoniker.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -43,3 +44,4 @@ namespace System.Runtime.InteropServices void Clone (out UCOMIEnumMoniker ppenum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumString.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumString.cs index 55e145af0a2..1f0599e28fe 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumString.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumString.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -45,3 +46,4 @@ namespace System.Runtime.InteropServices void Clone (out UCOMIEnumString ppenum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumVARIANT.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumVARIANT.cs index cb3b6832158..dbe383e0c80 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumVARIANT.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIEnumVARIANT.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -45,3 +46,4 @@ namespace System.Runtime.InteropServices void Clone (int ppenum); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIMoniker.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIMoniker.cs index 70b1f7f5186..08f7e4d176e 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIMoniker.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIMoniker.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -59,3 +60,4 @@ namespace System.Runtime.InteropServices void IsSystemMoniker (out int pdwMksys); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIPersistFile.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIPersistFile.cs index f09f6c69f3d..16516d7bb7f 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIPersistFile.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIPersistFile.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -45,3 +46,4 @@ namespace System.Runtime.InteropServices void GetCurFile ([MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIRunningObjectTable.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIRunningObjectTable.cs index fd07c710094..c4fc29df1d1 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIRunningObjectTable.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIRunningObjectTable.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -45,3 +46,4 @@ namespace System.Runtime.InteropServices void EnumRunning (out UCOMIEnumMoniker ppenumMoniker); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIStream.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIStream.cs index 8826673b885..f3bf95b915e 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMIStream.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMIStream.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -49,3 +50,4 @@ namespace System.Runtime.InteropServices void Clone (out UCOMIStream ppstm); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeComp.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeComp.cs index 07942f55cc2..12af145c4cd 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeComp.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeComp.cs @@ -28,6 +28,7 @@ // // (C) 2002 Ximian, Inc. +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -39,3 +40,4 @@ namespace System.Runtime.InteropServices void BindType([MarshalAs(UnmanagedType.LPWStr)] string szName, int lHashVal, out UCOMITypeInfo ppTInfo, out UCOMITypeComp ppTComp); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeInfo.cs index 679efcbdde2..a8b4a1600b6 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeInfo.cs @@ -28,6 +28,7 @@ // // (C) 2002 Ximian, Inc. +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -57,3 +58,4 @@ namespace System.Runtime.InteropServices } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeLib.cs b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeLib.cs index f2161fe106f..2b9c1ccdc0d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeLib.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/UCOMITypeLib.cs @@ -28,6 +28,7 @@ // // (C) 2002 Ximian, Inc. +#if !FULL_AOT_RUNTIME namespace System.Runtime.InteropServices { [Obsolete] @@ -51,3 +52,4 @@ namespace System.Runtime.InteropServices } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Activator.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Activator.cs index acabc729d6b..f6936f3075b 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Activator.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Activator.cs @@ -34,7 +34,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("03973551-57A1-3900-A2B5-9083E3FF2943")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (Activator))] +#endif public interface _Activator { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Assembly.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Assembly.cs index 29e234bf547..a30e29ce22d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Assembly.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Assembly.cs @@ -38,7 +38,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsDual)] [Guid ("17156360-2F1A-384A-BC52-FDE93C215C5B")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof(Assembly))] +#endif public interface _Assembly { string ToString (); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyBuilder.cs index db444ea3008..b86aae8483f 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyName.cs b/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyName.cs index ab72a0da60b..13f4659d74c 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyName.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_AssemblyName.cs @@ -34,7 +34,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("B42B6AAC-317E-34D5-9FA9-093BB4160C50")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (AssemblyName))] +#endif public interface _AssemblyName { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Attribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Attribute.cs index 46671e3d00e..f36abf3bbe5 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Attribute.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Attribute.cs @@ -33,7 +33,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("917B14D0-2D9E-38B8-92A9-381ACF52F7C0")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (Attribute))] +#endif public interface _Attribute { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorBuilder.cs index bc8f5fbbf35..9693bfb7649 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorInfo.cs index c11dbac76c5..7759e522297 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ConstructorInfo.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("E9A19478-9646-3679-9B10-8411AE1FD57D")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (ConstructorInfo))] +#endif [ComVisible (true)] public interface _ConstructorInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_CustomAttributeBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_CustomAttributeBuilder.cs index 18cab408e2e..412d7bb5b1f 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_CustomAttributeBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_CustomAttributeBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_EnumBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_EnumBuilder.cs index 94e59f3f67a..139ede6c6cc 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_EnumBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_EnumBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_EventBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_EventBuilder.cs index 06dab05220e..f3450bff76e 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_EventBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_EventBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_EventInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_EventInfo.cs index 5dfbb33b9ab..4b6aae76c3f 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_EventInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_EventInfo.cs @@ -13,7 +13,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("9DE59C64-D889-35A1-B897-587D74469E5B")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (EventInfo))] +#endif [ComVisible (true)] public interface _EventInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_FieldBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_FieldBuilder.cs index 6b3161aa860..c29f412456e 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_FieldBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_FieldBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_FieldInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_FieldInfo.cs index d599ee53659..4383dca5f66 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_FieldInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_FieldInfo.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("8A7C1442-A9FB-366B-80D8-4939FFA6DBE0")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (FieldInfo))] +#endif [ComVisible (true)] public interface _FieldInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ILGenerator.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ILGenerator.cs index c792633fb5d..66ae8ce32f4 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ILGenerator.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ILGenerator.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_LocalBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_LocalBuilder.cs index 63c337f2abb..7d6683b4983 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_LocalBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_LocalBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_MemberInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_MemberInfo.cs index 0b7e269fbf6..af5cc24b4c5 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_MemberInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_MemberInfo.cs @@ -13,7 +13,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("f7102fa9-cabb-3a74-a6da-b4567ef1b079")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (MemberInfo))] +#endif [ComVisible (true)] public interface _MemberInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_MethodBase.cs b/mcs/class/corlib/System.Runtime.InteropServices/_MethodBase.cs index aed2dee3a1a..ca9013200cc 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_MethodBase.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_MethodBase.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("6240837A-707F-3181-8E98-A36AE086766B")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (MethodBase))] +#endif [ComVisible (true)] public interface _MethodBase { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_MethodBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_MethodBuilder.cs index bd9e3995c0b..62abe9048b0 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_MethodBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_MethodBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_MethodInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_MethodInfo.cs index 14f6b719565..e8180ad7bf1 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_MethodInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_MethodInfo.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("FFCC1B5D-ECB8-38DD-9B01-3DC8ABC2AA5F")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (MethodInfo))] +#endif [ComVisible (true)] public interface _MethodInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_MethodRental.cs b/mcs/class/corlib/System.Runtime.InteropServices/_MethodRental.cs index 64c4745bd71..fb51ec66889 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_MethodRental.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_MethodRental.cs @@ -27,14 +27,18 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif namespace System.Runtime.InteropServices { [ComVisible (true)] [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("C2323C25-F57F-3880-8A4D-12EBEA7A5852")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (MethodRental))] +#endif public interface _MethodRental { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Module.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Module.cs index 3dd2f8220f3..53097c635fb 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Module.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Module.cs @@ -34,7 +34,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("D002E9BA-D9E3-3749-B1D3-D565A08B13E7")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (Module))] +#endif public interface _Module { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ModuleBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ModuleBuilder.cs index c029747044f..9e6fbe973fe 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ModuleBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ModuleBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ParameterBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ParameterBuilder.cs index 60c0ef2c160..c574f3b0f65 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ParameterBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ParameterBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_ParameterInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_ParameterInfo.cs index 28412992aab..ae4ed29dce0 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_ParameterInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_ParameterInfo.cs @@ -34,7 +34,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("993634C4-E47A-32CC-BE08-85F567DC27D6")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (ParameterInfo))] +#endif public interface _ParameterInfo { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_PropertyBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_PropertyBuilder.cs index 82206fc6907..0d45f6e3301 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_PropertyBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_PropertyBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -47,3 +48,4 @@ namespace System.Runtime.InteropServices { IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); } } +#endif diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_PropertyInfo.cs b/mcs/class/corlib/System.Runtime.InteropServices/_PropertyInfo.cs index e3041e9e1f5..12855f7862f 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_PropertyInfo.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_PropertyInfo.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("F59ED4E4-E68F-3218-BD77-061AA82824BF")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (PropertyInfo))] +#endif [ComVisible (true)] public interface _PropertyInfo { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_SignatureHelper.cs b/mcs/class/corlib/System.Runtime.InteropServices/_SignatureHelper.cs index b639e479635..0e0b941a431 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_SignatureHelper.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_SignatureHelper.cs @@ -27,14 +27,18 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif namespace System.Runtime.InteropServices { [ComVisible (true)] [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("7D13DD37-5A04-393C-BBCA-A5FEA802893D")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (SignatureHelper))] +#endif public interface _SignatureHelper { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Thread.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Thread.cs index 701dccf5b1a..68e647ba655 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Thread.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Thread.cs @@ -34,7 +34,9 @@ namespace System.Runtime.InteropServices { [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("C281C7F1-4AA9-3517-961A-463CFED57E75")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (Thread))] +#endif public interface _Thread { void GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_Type.cs b/mcs/class/corlib/System.Runtime.InteropServices/_Type.cs index 2fcc9682c76..1565230a30d 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_Type.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_Type.cs @@ -14,7 +14,9 @@ namespace System.Runtime.InteropServices [CLSCompliant (false)] [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] [Guid ("BCA8B44D-AAD6-3A86-8AB7-03349F4F2DA2")] +#if !FULL_AOT_RUNTIME [TypeLibImportClass (typeof (Type))] +#endif [ComVisible (true)] public interface _Type { diff --git a/mcs/class/corlib/System.Runtime.InteropServices/_TypeBuilder.cs b/mcs/class/corlib/System.Runtime.InteropServices/_TypeBuilder.cs index cc55bb2f1a0..b92f0b40ba8 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/_TypeBuilder.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/_TypeBuilder.cs @@ -27,6 +27,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; namespace System.Runtime.InteropServices { @@ -48,3 +49,4 @@ namespace System.Runtime.InteropServices { } } +#endif diff --git a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs index 322d815efad..4d4756e150d 100644 --- a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs +++ b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs @@ -37,7 +37,11 @@ using System.Security.Permissions; namespace System.Runtime.Serialization.Formatters.Binary { [ComVisible (true)] - public sealed class BinaryFormatter : IRemotingFormatter, IFormatter + public sealed class BinaryFormatter : +#if !FULL_AOT_RUNTIME + IRemotingFormatter, +#endif + IFormatter { private FormatterAssemblyStyle assembly_format = FormatterAssemblyStyle.Simple; private SerializationBinder binder; diff --git a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs index feb8ffa6d4e..fd38471644b 100644 --- a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs +++ b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs @@ -28,6 +28,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using System; using System.IO; using System.Collections; @@ -401,3 +402,4 @@ namespace System.Runtime.Serialization.Formatters.Binary } } +#endif diff --git a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs index d39348bd38d..9d3c42bbd19 100644 --- a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs +++ b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs @@ -469,11 +469,13 @@ namespace System.Runtime.Serialization.Formatters.Binary TypeMetadata CreateMemberTypeMetadata (Type type) { +#if !FULL_AOT_RUNTIME if (!BinaryCommon.UseReflectionSerialization) { Type metaType = CodeGenerator.GenerateMetadataType (type, _context); return (TypeMetadata) Activator.CreateInstance (metaType); } else +#endif return new MemberTypeMetadata (type, _context); } diff --git a/mcs/class/corlib/System.Security.Cryptography/AsymmetricAlgorithm.cs b/mcs/class/corlib/System.Security.Cryptography/AsymmetricAlgorithm.cs index 5109910cb1e..47ce386ebd8 100644 --- a/mcs/class/corlib/System.Security.Cryptography/AsymmetricAlgorithm.cs +++ b/mcs/class/corlib/System.Security.Cryptography/AsymmetricAlgorithm.cs @@ -93,7 +93,11 @@ namespace System.Security.Cryptography { public static AsymmetricAlgorithm Create () { +#if FULL_AOT_RUNTIME + return new RSACryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.AsymmetricAlgorithm"); +#endif } public static AsymmetricAlgorithm Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs index bb3a7399759..7720549e95b 100644 --- a/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs +++ b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs @@ -30,7 +30,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if !MOONLIGHT +#if !MOONLIGHT && !FULL_AOT_RUNTIME using System.Collections; using System.Collections.Generic; diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.fullaot.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.fullaot.cs new file mode 100755 index 00000000000..4d05e06ac4e --- /dev/null +++ b/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.fullaot.cs @@ -0,0 +1,220 @@ +// +// CryptoConfig.cs: Handles cryptographic implementations and OIDs mappings. +// +// Authors: +// Sebastien Pouliot (sebastien@xamarin.com) +// Tim Coleman (tim@timcoleman.com) +// +// (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) Tim Coleman, 2004 +// Copyright (C) 2004-2007,2011 Novell, Inc (http://www.novell.com) +// Copyright 2011 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 +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if FULL_AOT_RUNTIME + +// This is a special version of CryptoConfig that is not configurable and +// every "choice" is statiscally compiled. As long as CreateFromName is not +// used the linker will be able to eliminate the crypto code from the applications + +using System.Runtime.InteropServices; +using System.Security.Permissions; + +namespace System.Security.Cryptography { + + [ComVisible (true)] + public partial class CryptoConfig { + + // try to avoid hitting the CreateFromName overloads to help the linker + + public static object CreateFromName (string name) + { + return CreateFromName (name, null); + } + + [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)] + public static object CreateFromName (string name, params object[] args) + { + if (name == null) + throw new ArgumentNullException ("name"); + + switch (name.ToLowerInvariant ()) { + case "system.security.cryptography.dsacryptoserviceprovider": + case "system.security.cryptography.dsa": + case "dsa": + return new DSACryptoServiceProvider (); + case "system.security.cryptography.dsasignaturedeformatter": + return new DSASignatureDeformatter (); + case "system.security.cryptography.dsasignatureformatter": + return new DSASignatureFormatter (); + case "system.security.cryptography.dsasignaturedescription": + case "http://www.w3.org/2000/09/xmldsig#dsa-sha1": + return new DSASignatureDescription (); + case "system.security.cryptography.descryptoserviceprovider": + case "system.security.cryptography.des": + case "des": + return new DESCryptoServiceProvider (); + case "system.security.cryptography.hmacmd5": + case "hmacmd5": + return new HMACMD5 (); + case "system.security.cryptography.hmacripemd160": + case "hmacripemd160": + case "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160": + return new HMACRIPEMD160 (); + case "system.security.cryptography.keyedhashalgorithm": + case "system.security.cryptography.hmac": + case "system.security.cryptography.hmacsha1": + case "hmacsha1": + return new HMACSHA1 (); + case "system.security.cryptography.hmacsha256": + case "hmacsha256": + case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256": + return new HMACSHA256 (); + case "system.security.cryptography.hmacsha384": + case "hmacsha384": + case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384": + return new HMACSHA384 (); + case "system.security.cryptography.hmacsha512": + case "hmacsha512": + case "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512": + return new HMACSHA512 (); + case "system.security.cryptography.mactripledes": + case "mactripledes": + return new MACTripleDES (); + case "system.security.cryptography.md5cryptoserviceprovider": + case "system.security.cryptography.md5": + case "md5": + return new MD5CryptoServiceProvider (); + case "system.security.cryptography.rc2cryptoserviceprovider": + case "system.security.cryptography.rc2": + case "rc2": + return new RC2CryptoServiceProvider (); + case "system.security.cryptography.symmetricalgorithm": + case "system.security.cryptography.rijndaelmanaged": + case "system.security.cryptography.rijndael": + case "rijndael": + return new RijndaelManaged (); + case "system.security.cryptography.ripemd160managed": + case "system.security.cryptography.ripemd160": + case "ripemd-160": + case "ripemd160": + return new RIPEMD160Managed (); + case "system.security.cryptography.rngcryptoserviceprovider": + case "system.security.cryptography.randomnumbergenerator": + case "randomnumbergenerator": + return new RNGCryptoServiceProvider (); + case "system.security.cryptography.asymmetricalgorithm": + case "system.security.cryptography.rsa": + case "rsa": + return new RSACryptoServiceProvider (); + case "system.security.cryptography.rsapkcs1signaturedeformatter": + return new RSAPKCS1SignatureDeformatter (); + case "system.security.cryptography.rsapkcs1signatureformatter": + return new RSAPKCS1SignatureFormatter (); + case "system.security.cryptography.rsapkcs1sha1signaturedescription": + case "http://www.w3.org/2000/09/xmldsig#rsa-sha1": + return new RSAPKCS1SHA1SignatureDescription (); + case "system.security.cryptography.hashalgorithm": + case "system.security.cryptography.sha1": + case "system.security.cryptography.sha1cryptoserviceprovider": + case "sha1": + case "sha": + case "http://www.w3.org/2000/09/xmldsig#sha1": + return new SHA1CryptoServiceProvider (); + case "system.security.cryptography.sha1managed": + return new SHA1Managed (); + case "system.security.cryptography.sha256managed": + case "system.security.cryptography.sha256": + case "sha256": + case "sha-256": + case "http://www.w3.org/2001/04/xmlenc#sha256": + return new SHA256Managed (); + case "system.security.cryptography.sha384managed": + case "system.security.cryptography.sha384": + case "sha384": + case "sha-384": + return new SHA384Managed (); + case "system.security.cryptography.sha512managed": + case "system.security.cryptography.sha512": + case "sha512": + case "sha-512": + case "http://www.w3.org/2001/04/xmlenc#sha512": + return new SHA512Managed (); + case "system.security.cryptography.tripledescryptoserviceprovider": + case "system.security.cryptography.tripledes": + case "triple des": + case "tripledes": + case "3des": + return new TripleDESCryptoServiceProvider (); + default: + // method doesn't throw any exception + return null; + } + } + + public static string MapNameToOID (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + switch (name.ToLowerInvariant ()) { + case "system.security.cryptography.sha1cryptoserviceprovider": + case "system.security.cryptography.sha1managed": + case "system.security.cryptography.sha1": + case "sha1": + return "1.3.14.3.2.26"; + case "system.security.cryptography.md5cryptoserviceprovider": + case "system.security.cryptography.md5": + case "md5": + return "1.2.840.113549.2.5"; + case "system.security.cryptography.sha256managed": + case "system.security.cryptography.sha256": + case "sha256": + return "2.16.840.1.101.3.4.2.1"; + case "system.security.cryptography.sha384managed": + case "system.security.cryptography.sha384": + case "sha384": + return "2.16.840.1.101.3.4.2.2"; + case "system.security.cryptography.sha512managed": + case "system.security.cryptography.sha512": + case "sha512": + return "2.16.840.1.101.3.4.2.3"; + case "system.security.cryptography.ripemd160managed": + case "system.security.cryptography.ripemd160": + case "ripemd160": + return "1.3.36.3.2.1"; + case "tripledeskeywrap": + return "1.2.840.113549.1.9.16.3.6"; + case "des": + return "1.3.14.3.2.7"; + case "tripledes": + return "1.2.840.113549.3.7"; + case "rc2": + return "1.2.840.113549.3.2"; + default: + return null; + } + } + } +} + +#endif diff --git a/mcs/class/corlib/System.Security.Cryptography/DES.cs b/mcs/class/corlib/System.Security.Cryptography/DES.cs index ba69f162a3c..7c042cd9ddd 100644 --- a/mcs/class/corlib/System.Security.Cryptography/DES.cs +++ b/mcs/class/corlib/System.Security.Cryptography/DES.cs @@ -57,7 +57,11 @@ public abstract class DES : SymmetricAlgorithm { public static new DES Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.DESCryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.DES"); +#endif } public static new DES Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/DSA.cs b/mcs/class/corlib/System.Security.Cryptography/DSA.cs index 458abe92bcd..73abc4d4c4f 100644 --- a/mcs/class/corlib/System.Security.Cryptography/DSA.cs +++ b/mcs/class/corlib/System.Security.Cryptography/DSA.cs @@ -51,7 +51,11 @@ namespace System.Security.Cryptography { public static new DSA Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.DSACryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.DSA"); +#endif } public static new DSA Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/HMAC.cs b/mcs/class/corlib/System.Security.Cryptography/HMAC.cs index f3c5293e576..e2c20e29e1c 100644 --- a/mcs/class/corlib/System.Security.Cryptography/HMAC.cs +++ b/mcs/class/corlib/System.Security.Cryptography/HMAC.cs @@ -171,7 +171,11 @@ namespace System.Security.Cryptography { public static new HMAC Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.HMACSHA1 (); +#else return Create ("System.Security.Cryptography.HMAC"); +#endif } public static new HMAC Create (string algorithmName) diff --git a/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs b/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs index 8d769569736..07074f8aef3 100644 --- a/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs +++ b/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs @@ -112,7 +112,11 @@ namespace System.Security.Cryptography { public static HashAlgorithm Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.SHA1CryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.HashAlgorithm"); +#endif } public static HashAlgorithm Create (string hashName) diff --git a/mcs/class/corlib/System.Security.Cryptography/KeyedHashAlgorithm.cs b/mcs/class/corlib/System.Security.Cryptography/KeyedHashAlgorithm.cs index 616a8131654..abab189b249 100644 --- a/mcs/class/corlib/System.Security.Cryptography/KeyedHashAlgorithm.cs +++ b/mcs/class/corlib/System.Security.Cryptography/KeyedHashAlgorithm.cs @@ -79,7 +79,11 @@ public abstract class KeyedHashAlgorithm : HashAlgorithm { public static new KeyedHashAlgorithm Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.HMACSHA1 (); +#else return Create ("System.Security.Cryptography.KeyedHashAlgorithm"); +#endif } public static new KeyedHashAlgorithm Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/MD5.cs b/mcs/class/corlib/System.Security.Cryptography/MD5.cs index 4871d2bc17b..4d41fc7a211 100644 --- a/mcs/class/corlib/System.Security.Cryptography/MD5.cs +++ b/mcs/class/corlib/System.Security.Cryptography/MD5.cs @@ -44,7 +44,11 @@ namespace System.Security.Cryptography { public static new MD5 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.MD5CryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.MD5"); +#endif } public static new MD5 Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/RC2.cs b/mcs/class/corlib/System.Security.Cryptography/RC2.cs index 46b3780cc4f..5b6fc547f75 100644 --- a/mcs/class/corlib/System.Security.Cryptography/RC2.cs +++ b/mcs/class/corlib/System.Security.Cryptography/RC2.cs @@ -40,7 +40,11 @@ namespace System.Security.Cryptography { public static new RC2 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RC2CryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.RC2"); +#endif } public static new RC2 Create (string AlgName) diff --git a/mcs/class/corlib/System.Security.Cryptography/RIPEMD160.cs b/mcs/class/corlib/System.Security.Cryptography/RIPEMD160.cs index 2102a480c0f..4d67a691ec3 100644 --- a/mcs/class/corlib/System.Security.Cryptography/RIPEMD160.cs +++ b/mcs/class/corlib/System.Security.Cryptography/RIPEMD160.cs @@ -51,7 +51,11 @@ namespace System.Security.Cryptography { /// A new instance of the RIPEMD160 hash algorithm. public static new RIPEMD160 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RIPEMD160Managed (); +#else return Create ("System.Security.Cryptography.RIPEMD160"); +#endif } /// diff --git a/mcs/class/corlib/System.Security.Cryptography/RSA.cs b/mcs/class/corlib/System.Security.Cryptography/RSA.cs index 35a4b4bffe7..1a575931845 100644 --- a/mcs/class/corlib/System.Security.Cryptography/RSA.cs +++ b/mcs/class/corlib/System.Security.Cryptography/RSA.cs @@ -42,7 +42,11 @@ namespace System.Security.Cryptography { public static new RSA Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RSACryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.RSA"); +#endif } public static new RSA Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs b/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs index c8160ad4b72..0988ca54809 100644 --- a/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs +++ b/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs @@ -46,8 +46,12 @@ namespace System.Security.Cryptography { public static RandomNumberGenerator Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RNGCryptoServiceProvider (); +#else // create the default random number generator return Create ("System.Security.Cryptography.RandomNumberGenerator"); +#endif } public static RandomNumberGenerator Create (string rngName) diff --git a/mcs/class/corlib/System.Security.Cryptography/Rijndael.cs b/mcs/class/corlib/System.Security.Cryptography/Rijndael.cs index a1343db1b85..bf4a7e95ae9 100644 --- a/mcs/class/corlib/System.Security.Cryptography/Rijndael.cs +++ b/mcs/class/corlib/System.Security.Cryptography/Rijndael.cs @@ -42,7 +42,11 @@ namespace System.Security.Cryptography { public static new Rijndael Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RijndaelManaged (); +#else return Create ("System.Security.Cryptography.Rijndael"); +#endif } public static new Rijndael Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA1.cs b/mcs/class/corlib/System.Security.Cryptography/SHA1.cs index 56eddff59ae..9cc0ca7e64a 100644 --- a/mcs/class/corlib/System.Security.Cryptography/SHA1.cs +++ b/mcs/class/corlib/System.Security.Cryptography/SHA1.cs @@ -43,7 +43,11 @@ namespace System.Security.Cryptography { public static new SHA1 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.SHA1CryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.SHA1"); +#endif } public static new SHA1 Create (string hashName) diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA256.cs b/mcs/class/corlib/System.Security.Cryptography/SHA256.cs index 842a615e0cf..1af226c03e9 100644 --- a/mcs/class/corlib/System.Security.Cryptography/SHA256.cs +++ b/mcs/class/corlib/System.Security.Cryptography/SHA256.cs @@ -43,7 +43,11 @@ namespace System.Security.Cryptography { public static new SHA256 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.SHA256Managed (); +#else return Create ("System.Security.Cryptography.SHA256"); +#endif } public static new SHA256 Create (string hashName) diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA384.cs b/mcs/class/corlib/System.Security.Cryptography/SHA384.cs index 2daff34a694..93b6f7f64de 100644 --- a/mcs/class/corlib/System.Security.Cryptography/SHA384.cs +++ b/mcs/class/corlib/System.Security.Cryptography/SHA384.cs @@ -45,7 +45,11 @@ namespace System.Security.Cryptography { public static new SHA384 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.SHA384Managed (); +#else return Create ("System.Security.Cryptography.SHA384"); +#endif } public static new SHA384 Create (string hashName) diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA512.cs b/mcs/class/corlib/System.Security.Cryptography/SHA512.cs index 00baef00d08..ccded95bfd3 100644 --- a/mcs/class/corlib/System.Security.Cryptography/SHA512.cs +++ b/mcs/class/corlib/System.Security.Cryptography/SHA512.cs @@ -45,7 +45,11 @@ namespace System.Security.Cryptography { public static new SHA512 Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.SHA512Managed (); +#else return Create ("System.Security.Cryptography.SHA512"); +#endif } public static new SHA512 Create (string hashName) diff --git a/mcs/class/corlib/System.Security.Cryptography/SymmetricAlgorithm.cs b/mcs/class/corlib/System.Security.Cryptography/SymmetricAlgorithm.cs index 1a331415c2f..60b57e7e753 100644 --- a/mcs/class/corlib/System.Security.Cryptography/SymmetricAlgorithm.cs +++ b/mcs/class/corlib/System.Security.Cryptography/SymmetricAlgorithm.cs @@ -229,7 +229,11 @@ namespace System.Security.Cryptography { // LAMESPEC: Default is Rijndael - not TripleDES public static SymmetricAlgorithm Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.RijndaelManaged (); +#else return Create ("System.Security.Cryptography.SymmetricAlgorithm"); +#endif } public static SymmetricAlgorithm Create (string algName) diff --git a/mcs/class/corlib/System.Security.Cryptography/TripleDES.cs b/mcs/class/corlib/System.Security.Cryptography/TripleDES.cs index 0bc887a15a3..3fa0800cdff 100644 --- a/mcs/class/corlib/System.Security.Cryptography/TripleDES.cs +++ b/mcs/class/corlib/System.Security.Cryptography/TripleDES.cs @@ -121,7 +121,11 @@ public abstract class TripleDES : SymmetricAlgorithm { public static new TripleDES Create () { +#if FULL_AOT_RUNTIME + return new System.Security.Cryptography.TripleDESCryptoServiceProvider (); +#else return Create ("System.Security.Cryptography.TripleDES"); +#endif } public static new TripleDES Create (string str) diff --git a/mcs/class/corlib/System.Security.Permissions/CodeAccessSecurityAttribute.cs b/mcs/class/corlib/System.Security.Permissions/CodeAccessSecurityAttribute.cs index 4e89bdc1d71..5714862cbde 100644 --- a/mcs/class/corlib/System.Security.Permissions/CodeAccessSecurityAttribute.cs +++ b/mcs/class/corlib/System.Security.Permissions/CodeAccessSecurityAttribute.cs @@ -31,7 +31,7 @@ using System.Runtime.InteropServices; namespace System.Security.Permissions { -#if NET_2_1 +#if NET_2_1 && !MONOTOUCH [Obsolete ("CAS support is not available with Silverlight applications.")] #endif [ComVisible (true)] diff --git a/mcs/class/corlib/System.Security.Permissions/SecurityAction.cs b/mcs/class/corlib/System.Security.Permissions/SecurityAction.cs index 6d579b30ed3..9a20872424b 100644 --- a/mcs/class/corlib/System.Security.Permissions/SecurityAction.cs +++ b/mcs/class/corlib/System.Security.Permissions/SecurityAction.cs @@ -35,7 +35,7 @@ using System.Runtime.InteropServices; namespace System.Security.Permissions { -#if NET_2_1 +#if NET_2_1 && !MONOTOUCH [Obsolete ("CAS support is not available with Silverlight applications.")] #endif [ComVisible (true)] diff --git a/mcs/class/corlib/System.Security.Permissions/SecurityAttribute.cs b/mcs/class/corlib/System.Security.Permissions/SecurityAttribute.cs index 9891c25f6b8..f871175e423 100644 --- a/mcs/class/corlib/System.Security.Permissions/SecurityAttribute.cs +++ b/mcs/class/corlib/System.Security.Permissions/SecurityAttribute.cs @@ -31,7 +31,7 @@ using System.Runtime.InteropServices; namespace System.Security.Permissions { -#if NET_2_1 +#if NET_2_1 && !MONOTOUCH [Obsolete ("CAS support is not available with Silverlight applications.")] #endif [ComVisible (true)] diff --git a/mcs/class/corlib/System.Security.Permissions/SecurityPermissionAttribute.cs b/mcs/class/corlib/System.Security.Permissions/SecurityPermissionAttribute.cs index 8b45709549a..cf37722731b 100644 --- a/mcs/class/corlib/System.Security.Permissions/SecurityPermissionAttribute.cs +++ b/mcs/class/corlib/System.Security.Permissions/SecurityPermissionAttribute.cs @@ -31,7 +31,7 @@ using System.Runtime.InteropServices; namespace System.Security.Permissions { -#if NET_2_1 +#if NET_2_1 && !MONOTOUCH [Obsolete ("CAS support is not available with Silverlight applications.")] #endif [ComVisible (true)] diff --git a/mcs/class/corlib/System.Security.Permissions/SecurityPermissionFlag.cs b/mcs/class/corlib/System.Security.Permissions/SecurityPermissionFlag.cs index 78afc430071..9e5517bd406 100644 --- a/mcs/class/corlib/System.Security.Permissions/SecurityPermissionFlag.cs +++ b/mcs/class/corlib/System.Security.Permissions/SecurityPermissionFlag.cs @@ -34,7 +34,7 @@ using System.Runtime.InteropServices; namespace System.Security.Permissions { -#if NET_2_1 +#if NET_2_1 && !MONOTOUCH [Obsolete ("CAS support is not available with Silverlight applications.")] #endif [ComVisible (true)] diff --git a/mcs/class/corlib/System.Security/SecurityManager_mobile.cs b/mcs/class/corlib/System.Security/SecurityManager_mobile.cs index ebda6ccbe7d..69b7e7fd4d0 100644 --- a/mcs/class/corlib/System.Security/SecurityManager_mobile.cs +++ b/mcs/class/corlib/System.Security/SecurityManager_mobile.cs @@ -59,13 +59,13 @@ namespace System.Security { [Obsolete] #endif public static bool CheckExecutionRights { - get { return true; } + get { return false; } set { ; } } [Obsolete ("The security manager cannot be turned off on MS runtime")] public static bool SecurityEnabled { - get { return true; } + get { return false; } set { ; } } diff --git a/mcs/class/corlib/System.Threading.Tasks/Parallel.cs b/mcs/class/corlib/System.Threading.Tasks/Parallel.cs index d3bcc94e917..cc79daf734f 100644 --- a/mcs/class/corlib/System.Threading.Tasks/Parallel.cs +++ b/mcs/class/corlib/System.Threading.Tasks/Parallel.cs @@ -46,14 +46,14 @@ namespace System.Threading.Tasks internal static int GetBestWorkerNumber (TaskScheduler scheduler) { - return scheduler.MaximumConcurrencyLevel; + return Math.Min (Environment.ProcessorCount, (scheduler ?? TaskScheduler.Current).MaximumConcurrencyLevel); } static int GetBestWorkerNumber (int from, int to, ParallelOptions options, out int step) { int num = GetBestWorkerNumber(options.TaskScheduler); if (options != null && options.MaxDegreeOfParallelism != -1) - num = options.MaxDegreeOfParallelism; + num = Math.Min (options.MaxDegreeOfParallelism, num); // Integer range that each task process if ((step = (to - from) / num) < 5) { step = 5; @@ -343,7 +343,7 @@ namespace System.Threading.Tasks if (destruct == null) throw new ArgumentNullException ("destruct"); - int num = Math.Min (GetBestWorkerNumber (), + int num = Math.Min (GetBestWorkerNumber (options.TaskScheduler), options != null && options.MaxDegreeOfParallelism != -1 ? options.MaxDegreeOfParallelism : int.MaxValue); Task[] tasks = new Task[num]; diff --git a/mcs/class/corlib/System.Threading.Tasks/Task.cs b/mcs/class/corlib/System.Threading.Tasks/Task.cs index fdf85a5c667..2542ad63b0d 100644 --- a/mcs/class/corlib/System.Threading.Tasks/Task.cs +++ b/mcs/class/corlib/System.Threading.Tasks/Task.cs @@ -461,6 +461,15 @@ namespace System.Threading.Tasks return true; } + internal bool TrySetExceptionObserved () + { + if (exSlot != null) { + exSlot.Observed = true; + return true; + } + return false; + } + internal void Execute () { ThreadStart (); diff --git a/mcs/class/corlib/System.Threading.Tasks/TaskActionInvoker.cs b/mcs/class/corlib/System.Threading.Tasks/TaskActionInvoker.cs index 40907671bff..88746381daa 100644 --- a/mcs/class/corlib/System.Threading.Tasks/TaskActionInvoker.cs +++ b/mcs/class/corlib/System.Threading.Tasks/TaskActionInvoker.cs @@ -132,6 +132,7 @@ namespace System.Threading.Tasks public override void Invoke (Task owner, object state, Task context) { + owner.TrySetExceptionObserved (); action (tasks); } } @@ -281,6 +282,7 @@ namespace System.Threading.Tasks public override void Invoke (Task owner, object state, Task context) { + owner.TrySetExceptionObserved (); ((Task) context).Result = action (tasks); } } @@ -469,6 +471,8 @@ namespace System.Threading.Tasks return new FuncTaskObjectInvoke (action); } + #region Used by ContinueWhenAll + public static TaskActionInvoker Create (Action action, Task[] tasks) { return new ActionTasksInvoke (action, tasks); @@ -479,7 +483,9 @@ namespace System.Threading.Tasks return new FuncTasksInvoke (action, tasks); } - #region Used by WhenAny + #endregion + + #region Used by ContinueWhenAny public static TaskActionInvoker CreateSelected (Action action) { diff --git a/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs b/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs index 0c4ba2a0926..0ac088c9058 100644 --- a/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs +++ b/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs @@ -339,14 +339,13 @@ namespace System.Threading.Tasks throw new ArgumentOutOfRangeException ("creationOptions"); var tcs = new TaskCompletionSource (state, creationOptions); - var alreadyInvoked = false; + var alreadyInvoked = new AtomicBoolean (); var iar = beginMethod (l => { - alreadyInvoked = true; - InnerInvoke (tcs, endMethod, l); + if (alreadyInvoked.TryRelaxedSet ()) + InnerInvoke (tcs, endMethod, l); }, state); - if (iar != null && !alreadyInvoked && iar.CompletedSynchronously) { + if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ()) InnerInvoke (tcs, endMethod, iar); - } return tcs.Task; } @@ -377,14 +376,13 @@ namespace System.Threading.Tasks throw new ArgumentOutOfRangeException ("creationOptions"); var tcs = new TaskCompletionSource (state, creationOptions); - var alreadyInvoked = false; + var alreadyInvoked = new AtomicBoolean (); var iar = beginMethod (arg1, l => { - alreadyInvoked = true; - InnerInvoke (tcs, endMethod, l); + if (alreadyInvoked.TryRelaxedSet ()) + InnerInvoke (tcs, endMethod, l); }, state); - if (iar != null && !alreadyInvoked && iar.CompletedSynchronously) { + if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ()) InnerInvoke (tcs, endMethod, iar); - } return tcs.Task; } @@ -414,14 +412,13 @@ namespace System.Threading.Tasks throw new ArgumentOutOfRangeException ("creationOptions"); var tcs = new TaskCompletionSource (state, creationOptions); - var alreadyInvoked = false; + var alreadyInvoked = new AtomicBoolean (); var iar = beginMethod (arg1, arg2, l => { - alreadyInvoked = true; - InnerInvoke (tcs, endMethod, l); + if (alreadyInvoked.TryRelaxedSet ()) + InnerInvoke (tcs, endMethod, l); }, state); - if (iar != null && !alreadyInvoked && iar.CompletedSynchronously) { + if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ()) InnerInvoke (tcs, endMethod, iar); - } return tcs.Task; } @@ -452,14 +449,13 @@ namespace System.Threading.Tasks throw new ArgumentOutOfRangeException ("creationOptions"); var tcs = new TaskCompletionSource (state, creationOptions); - bool alreadyInvoked = false; + var alreadyInvoked = new AtomicBoolean (); var iar = beginMethod (arg1, arg2, arg3, l => { - alreadyInvoked = true; - InnerInvoke (tcs, endMethod, l); + if (alreadyInvoked.TryRelaxedSet ()) + InnerInvoke (tcs, endMethod, l); }, state); - if (iar != null && !alreadyInvoked && iar.CompletedSynchronously) { + if (iar != null && iar.CompletedSynchronously && alreadyInvoked.TryRelaxedSet ()) InnerInvoke (tcs, endMethod, iar); - } return tcs.Task; } diff --git a/mcs/class/corlib/System.Threading.Tasks/TaskScheduler.cs b/mcs/class/corlib/System.Threading.Tasks/TaskScheduler.cs index 71abd1c75bb..ad3ce1f4ec8 100644 --- a/mcs/class/corlib/System.Threading.Tasks/TaskScheduler.cs +++ b/mcs/class/corlib/System.Threading.Tasks/TaskScheduler.cs @@ -103,7 +103,7 @@ namespace System.Threading.Tasks public virtual int MaximumConcurrencyLevel { get { - return Environment.ProcessorCount; + return int.MaxValue; } } diff --git a/mcs/class/corlib/System.Threading/NativeOverlapped.cs b/mcs/class/corlib/System.Threading/NativeOverlapped.cs index 3d999538ee2..161a2ad0a9d 100644 --- a/mcs/class/corlib/System.Threading/NativeOverlapped.cs +++ b/mcs/class/corlib/System.Threading/NativeOverlapped.cs @@ -1,14 +1,13 @@ // // System.Threading.NativeOverlapped.cs // -// Author: +// Authors: // Dick Porter (dick@ximian.com) +// Marek Safar (marek.safar@gmail.com) // // (C) Ximian, Inc. http://www.ximian.com -// - -// // Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// Copyright 2012 Xamarin Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -35,27 +34,13 @@ using System.Runtime.InteropServices; namespace System.Threading { [ComVisible (true)] - public struct NativeOverlapped { - public IntPtr EventHandle; - public IntPtr InternalHigh; + public struct NativeOverlapped + { public IntPtr InternalLow; - public int OffsetHigh; + public IntPtr InternalHigh; public int OffsetLow; - - // (fields disappeared beta2 -> 1.0) - // public GCHandle ReservedClassLib; - // public int ReservedCOR1; - // public GCHandle ReservedCOR2; - - // P.S. (Gonzalo): try this: - // Console.WriteLine (Marshal.SizeOf (typeof (NativeOverlapped))); - // - // And you'll get a nice 36. So probably those fields are out there but are not public. - // So I'm adding some internal fields that are used in the runtime -#pragma warning disable 649 - internal int Handle1; - internal int Handle2; -#pragma warning restore 649 + public int OffsetHigh; + public IntPtr EventHandle; } } diff --git a/mcs/class/corlib/System/AppDomain.cs b/mcs/class/corlib/System/AppDomain.cs index 1cb3be10c3b..7032f7054f5 100644 --- a/mcs/class/corlib/System/AppDomain.cs +++ b/mcs/class/corlib/System/AppDomain.cs @@ -37,7 +37,9 @@ using System.Collections; using System.Globalization; using System.IO; using System.Reflection; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Threading; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -314,6 +316,7 @@ namespace System { { return Activator.CreateComInstanceFrom (assemblyFile, typeName, hashValue ,hashAlgorithm); } +#endif #endif public ObjectHandle CreateInstance (string assemblyName, string typeName) @@ -467,8 +470,7 @@ namespace System { return (oh != null) ? oh.Unwrap () : null; } -#endif // !NET_2_1 - +#if !FULL_AOT_RUNTIME public AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access) { return DefineDynamicAssembly (name, access, null, null, null, null, null, false); @@ -606,6 +608,7 @@ namespace System { { return new AssemblyBuilder (name, null, access, true); } +#endif // // AppDomain.DoCallBack works because AppDomain is a MarshalByRefObject @@ -1297,9 +1300,11 @@ namespace System { string name; +#if !FULL_AOT_RUNTIME if (name_or_tb is TypeBuilder) name = ((TypeBuilder) name_or_tb).FullName; else +#endif name = (string) name_or_tb; /* Prevent infinite recursion */ diff --git a/mcs/class/corlib/System/Array.cs b/mcs/class/corlib/System/Array.cs index 48e51d267e9..be3f8eebe1a 100644 --- a/mcs/class/corlib/System/Array.cs +++ b/mcs/class/corlib/System/Array.cs @@ -40,7 +40,9 @@ using System.Runtime.InteropServices; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.ConstrainedExecution; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif namespace System { @@ -673,8 +675,10 @@ namespace System throw new NotSupportedException ("Array type can not be void"); if (elementType.ContainsGenericParameters) throw new NotSupportedException ("Array type can not be an open generic type"); +#if !FULL_AOT_RUNTIME if ((elementType is TypeBuilder) && !(elementType as TypeBuilder).IsCreated ()) throw new NotSupportedException ("Can't create an array of the unfinished type '" + elementType + "'."); +#endif return CreateInstanceImpl (elementType, lengths, bounds); } diff --git a/mcs/class/corlib/System/Console.cs b/mcs/class/corlib/System/Console.cs index 45b721a0c5a..fe0f229e396 100644 --- a/mcs/class/corlib/System/Console.cs +++ b/mcs/class/corlib/System/Console.cs @@ -158,12 +158,21 @@ namespace System stdin = new CStreamReader (OpenStandardInput (0), inputEncoding); } else { #endif +#if FULL_AOT_RUNTIME + Type nslogwriter = Type.GetType ("MonoTouch.Foundation.NSLogWriter, monotouch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"); + stdout = (TextWriter) Activator.CreateInstance (nslogwriter); +#else stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding); ((StreamWriter)stdout).AutoFlush = true; +#endif stdout = TextWriter.Synchronized (stdout, true); +#if FULL_AOT_RUNTIME + stderr = (TextWriter) Activator.CreateInstance (nslogwriter); +#else stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding); ((StreamWriter)stderr).AutoFlush = true; +#endif stderr = TextWriter.Synchronized (stderr, true); stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding); diff --git a/mcs/class/corlib/System/Delegate.cs b/mcs/class/corlib/System/Delegate.cs index cfb8fdf171d..0ca565e9ab9 100644 --- a/mcs/class/corlib/System/Delegate.cs +++ b/mcs/class/corlib/System/Delegate.cs @@ -565,7 +565,11 @@ namespace System internal bool IsTransparentProxy () { +#if MONOTOUCH + return false; +#else return RemotingServices.IsTransparentProxy (m_target); +#endif } } } diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs index 0571215dafd..3f8878b0439 100644 --- a/mcs/class/corlib/System/Environment.cs +++ b/mcs/class/corlib/System/Environment.cs @@ -56,7 +56,7 @@ namespace System { * of icalls, do not require an increment. */ #pragma warning disable 169 - private const int mono_corlib_version = 107; + private const int mono_corlib_version = 108; #pragma warning restore 169 [ComVisible (true)] diff --git a/mcs/class/corlib/System/Guid.cs b/mcs/class/corlib/System/Guid.cs index 85af5b1cd37..e8dd2247d51 100644 --- a/mcs/class/corlib/System/Guid.cs +++ b/mcs/class/corlib/System/Guid.cs @@ -464,12 +464,17 @@ namespace System { } private static object _rngAccess = new object (); +#if !FULL_AOT_RUNTIME private static RandomNumberGenerator _rng; private static RandomNumberGenerator _fastRng; +#else + private static object _fastRng; +#endif // generated as per section 3.4 of the specification public static Guid NewGuid () { +#if !FULL_AOT_RUNTIME byte[] b = new byte [16]; // thread-safe access to the prng @@ -478,6 +483,10 @@ namespace System { _rng = RandomNumberGenerator.Create (); _rng.GetBytes (b); } +#else + byte[] b = FastNewGuidArray (); +#endif + Guid res = new Guid (b); // Mask in Variant 1-0 in Bit[7..6] @@ -497,12 +506,18 @@ namespace System { // thread-safe access to the prng lock (_rngAccess) { // if known, use preferred RNG +#if FULL_AOT_RUNTIME + if (_fastRng == null) + _fastRng = new RNGCryptoServiceProvider (); + (_fastRng as RNGCryptoServiceProvider).GetBytes (guid); +#else if (_rng != null) _fastRng = _rng; // else use hardcoded default RNG (bypassing CryptoConfig) if (_fastRng == null) _fastRng = new RNGCryptoServiceProvider (); _fastRng.GetBytes (guid); +#endif } // Mask in Variant 1-0 in Bit[7..6] diff --git a/mcs/class/corlib/System/MonoCustomAttrs.cs b/mcs/class/corlib/System/MonoCustomAttrs.cs index 15a58c0be47..14641fbe661 100644 --- a/mcs/class/corlib/System/MonoCustomAttrs.cs +++ b/mcs/class/corlib/System/MonoCustomAttrs.cs @@ -35,7 +35,10 @@ using System; using System.Reflection; using System.Collections; using System.Runtime.CompilerServices; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif + using System.Collections.Generic; namespace System @@ -48,7 +51,11 @@ namespace System static bool IsUserCattrProvider (object obj) { Type type = obj as Type; +#if !FULL_AOT_RUNTIME if ((type is MonoType) || (type is TypeBuilder)) +#else + if (type is MonoType) +#endif return false; if ((obj is Type)) return true; diff --git a/mcs/class/corlib/System/String.cs b/mcs/class/corlib/System/String.cs index 91f24fb835f..fb595c643b2 100644 --- a/mcs/class/corlib/System/String.cs +++ b/mcs/class/corlib/System/String.cs @@ -769,16 +769,30 @@ namespace System public static int CompareOrdinal (String strA, int indexA, String strB, int indexB, int length) { - if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0)) - throw new ArgumentOutOfRangeException (); + if (strA != null && strB != null) + { + if (indexA > strA.Length || indexA < 0) + throw new ArgumentOutOfRangeException ("indexA"); + if (indexB > strB.Length || indexB < 0) + throw new ArgumentOutOfRangeException ("indexB"); + if (length < 0) + throw new ArgumentOutOfRangeException ("length"); + } return CompareOrdinalUnchecked (strA, indexA, length, strB, indexB, length); } internal static int CompareOrdinalCaseInsensitive (String strA, int indexA, String strB, int indexB, int length) { - if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0)) - throw new ArgumentOutOfRangeException (); + if (strA != null && strB != null) + { + if (indexA > strA.Length || indexA < 0) + throw new ArgumentOutOfRangeException ("indexA"); + if (indexB > strB.Length || indexB < 0) + throw new ArgumentOutOfRangeException ("indexB"); + if (length < 0) + throw new ArgumentOutOfRangeException ("length"); + } return CompareOrdinalCaseInsensitiveUnchecked (strA, indexA, length, strB, indexB, length); } @@ -815,11 +829,9 @@ namespace System { // Same as above, but checks versus uppercase characters if (strA == null) { - if (strB == null) - return 0; - else - return -1; - } else if (strB == null) { + return strB == null ? 0 : -1; + } + if (strB == null) { return 1; } int lengthA = Math.Min (lenA, strA.Length - indexA); diff --git a/mcs/class/corlib/System/Type.cs b/mcs/class/corlib/System/Type.cs index 327c15b889c..8371a43b4f5 100644 --- a/mcs/class/corlib/System/Type.cs +++ b/mcs/class/corlib/System/Type.cs @@ -33,7 +33,9 @@ using System.Diagnostics; using System.Reflection; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -708,8 +710,10 @@ namespace System { Type type = this; if (type is MonoType) return GetTypeCodeInternal (type); +#if !FULL_AOT_RUNTIME if (type is TypeBuilder) return ((TypeBuilder)type).GetTypeCodeInternal (); +#endif type = type.UnderlyingSystemType; @@ -876,8 +880,10 @@ namespace System { if (Equals (c)) return true; +#if !FULL_AOT_RUNTIME if (c is TypeBuilder) return ((TypeBuilder)c).IsAssignableTo (this); +#endif /* Handle user defined type classes */ if (!IsSystemType) { @@ -1436,9 +1442,11 @@ namespace System { systemTypes [i] = t; } +#if !FULL_AOT_RUNTIME if (hasUserType) { return new MonoGenericClass (this, typeArguments); } +#endif Type res = MakeGenericType (this, systemTypes); if (res == null) diff --git a/mcs/class/corlib/System/Variant.cs b/mcs/class/corlib/System/Variant.cs index 6f95b81f651..b531d1725f5 100644 --- a/mcs/class/corlib/System/Variant.cs +++ b/mcs/class/corlib/System/Variant.cs @@ -168,6 +168,7 @@ namespace System vt = (short)VarEnum.VT_BSTR; bstrVal = Marshal.StringToBSTR(((BStrWrapper)obj).WrappedObject); } +#if !FULL_AOT_RUNTIME else if (t == typeof (UnknownWrapper)) { vt = (short)VarEnum.VT_UNKNOWN; @@ -178,8 +179,12 @@ namespace System vt = (short)VarEnum.VT_DISPATCH; pdispVal = Marshal.GetIDispatchForObject(((DispatchWrapper)obj).WrappedObject); } +#endif else { +#if FULL_AOT_RUNTIME + throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType())); +#else try { pdispVal = Marshal.GetIDispatchForObject(obj); @@ -196,6 +201,7 @@ namespace System { throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()), ex); } +#endif } } @@ -239,11 +245,13 @@ namespace System case VarEnum.VT_BSTR: obj = Marshal.PtrToStringBSTR(bstrVal); break; +#if !FULL_AOT_RUNTIME case VarEnum.VT_UNKNOWN: case VarEnum.VT_DISPATCH: if (pdispVal != IntPtr.Zero) obj = Marshal.GetObjectForIUnknown(pdispVal); break; +#endif } return obj; } diff --git a/mcs/class/corlib/System/_AppDomain.cs b/mcs/class/corlib/System/_AppDomain.cs index 5dd7257c4a0..de5103a639a 100644 --- a/mcs/class/corlib/System/_AppDomain.cs +++ b/mcs/class/corlib/System/_AppDomain.cs @@ -31,7 +31,9 @@ using System.Security.Permissions; using System.Security.Policy; using System.Security.Principal; using System.Reflection; +#if !FULL_AOT_RUNTIME using System.Reflection.Emit; +#endif using System.Globalization; using System.Runtime.Remoting; using System.Runtime.InteropServices; @@ -77,6 +79,8 @@ namespace System BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes, Evidence securityAttributes); #endif + +#if !FULL_AOT_RUNTIME AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access); AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, Evidence evidence); AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir); @@ -94,6 +98,7 @@ namespace System AssemblyBuilder DefineDynamicAssembly (AssemblyName name, AssemblyBuilderAccess access, string dir, Evidence evidence, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions, bool isSynchronized); +#endif void DoCallBack (CrossAppDomainDelegate theDelegate); bool Equals (object other); diff --git a/mcs/class/corlib/System/__ComObject.cs b/mcs/class/corlib/System/__ComObject.cs index be730629002..18f0c43ec49 100644 --- a/mcs/class/corlib/System/__ComObject.cs +++ b/mcs/class/corlib/System/__ComObject.cs @@ -32,6 +32,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +#if !FULL_AOT_RUNTIME using Mono.Interop; using System.Collections; using System.Runtime.InteropServices; @@ -229,3 +230,4 @@ namespace System out IntPtr pUnk); } } +#endif diff --git a/mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs b/mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs index 055ccb9485f..e1d7796e44b 100644 --- a/mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs +++ b/mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs @@ -236,6 +236,20 @@ namespace MonoTests.System.Threading.Tasks } } + [Test] + public void ContinueWhenAll_WithExceptions () + { + var t1 = Task.Factory.StartNew (() => { throw new ApplicationException ("Foo"); }); + var t2 = Task.Factory.StartNew (() => { throw new ApplicationException ("Bar"); }); + + var cont = Task.Factory.ContinueWhenAll (new[] { t1, t2 }, delegate {}); + cont.Wait (200); + + Assert.IsTrue (t1.IsFaulted); + Assert.IsTrue (t2.IsFaulted); + Assert.AreEqual (TaskStatus.RanToCompletion, cont.Status); + } + [Test] public void ContinueWhenAny_Simple () { diff --git a/mcs/class/corlib/Test/System.Threading/WaitHandleTest.cs b/mcs/class/corlib/Test/System.Threading/WaitHandleTest.cs index 47289d77d01..0e515c2b7cf 100644 --- a/mcs/class/corlib/Test/System.Threading/WaitHandleTest.cs +++ b/mcs/class/corlib/Test/System.Threading/WaitHandleTest.cs @@ -315,6 +315,87 @@ namespace MonoTests.System.Threading { WaitHandle.WaitAny (new WaitHandle [0]); } + [Test] + public void InterrupedWaitAny () + { + using (var m1 = new Mutex (true)) { + using (var m2 = new Mutex (true)) { + using (var done = new ManualResetEvent (false)) { + var thread = new Thread (() => + { + try { + WaitHandle.WaitAny (new WaitHandle [] { m1, m2 }); + } catch (ThreadInterruptedException) { + done.Set (); + } + }); + thread.Start (); + Thread.Sleep (100); // wait a bit so the thread can enter its wait + thread.Interrupt (); + + Assert.IsTrue (thread.Join (1000), "Join"); + Assert.IsTrue (done.WaitOne (1000), "done"); + + m1.ReleaseMutex (); + m2.ReleaseMutex (); + } + } + } + } + + [Test] + public void InterrupedWaitAll () + { + using (var m1 = new Mutex (true)) { + using (var m2 = new Mutex (true)) { + using (var done = new ManualResetEvent (false)) { + var thread = new Thread (() => + { + try { + WaitHandle.WaitAll (new WaitHandle [] { m1, m2 }); + } catch (ThreadInterruptedException) { + done.Set (); + } + }); + thread.Start (); + Thread.Sleep (100); // wait a bit so the thread can enter its wait + thread.Interrupt (); + + Assert.IsTrue (thread.Join (1000), "Join"); + Assert.IsTrue (done.WaitOne (1000), "done"); + + m1.ReleaseMutex (); + m2.ReleaseMutex (); + } + } + } + } + + [Test] + public void InterrupedWaitOne () + { + using (var m1 = new Mutex (true)) { + using (var done = new ManualResetEvent (false)) { + var thread = new Thread (() => + { + try { + m1.WaitOne (); + } catch (ThreadInterruptedException) { + done.Set (); + } + }); + thread.Start (); + Thread.Sleep (100); // wait a bit so the thread can enter its wait + thread.Interrupt (); + + Assert.IsTrue (thread.Join (1000), "Join"); + Assert.IsTrue (done.WaitOne (1000), "done"); + + m1.ReleaseMutex (); + } + } + } + } } diff --git a/mcs/class/corlib/Test/System/StringTest.cs b/mcs/class/corlib/Test/System/StringTest.cs index ab1ba7080b6..ffa822b6aee 100644 --- a/mcs/class/corlib/Test/System/StringTest.cs +++ b/mcs/class/corlib/Test/System/StringTest.cs @@ -658,6 +658,23 @@ public class StringTest Assert.IsTrue (string.CompareOrdinal (ab2, 0, ab1, 1, 1) < 0, "#2"); } + [Test] + public void CompareOrdinalSubstringWithNull () + { + string lesser = "abc"; + string greater = "xyz"; + + Assert.AreEqual (0, string.CompareOrdinal (null, 0, null, 0, 0), "substring both null"); + Assert.AreEqual (-1, string.CompareOrdinal (null, 0, greater, 0, 0), "substring strA null"); + Assert.AreEqual (-1, string.CompareOrdinal (null, 4, greater, 0, 0), "substring strA null; indexA greater than strA.Length"); + Assert.AreEqual (-1, string.CompareOrdinal (null, 0, greater, 4, 0), "substring strA null; indexB greater than strB.Length"); + Assert.AreEqual (-1, string.CompareOrdinal (null, -1, greater, -1, -1), "substring strA null; indexA, indexB, length negative"); + Assert.AreEqual (1, string.CompareOrdinal (lesser, 0, null, 0, 0), "substring strB null"); + Assert.AreEqual (1, string.CompareOrdinal (lesser, 4, null, 0, 0), "substring strB null; indexA greater than strA.Length"); + Assert.AreEqual (1, string.CompareOrdinal (lesser, 0, null, 4, 0), "substring strB null; indexB greater than strB.Length"); + Assert.AreEqual (1, string.CompareOrdinal (lesser, -1, null, -1, -1), "substring strB null; indexA, indexB, length negative"); + } + [Test] public void CompareTo () { diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index e1b8ba133d2..26fe3bb9554 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -1272,6 +1272,7 @@ System.Security.Cryptography/CipherMode.cs System.Security.Cryptography/CryptoAPITransform.cs System.Security.Cryptography/CryptoConfig.cs System.Security.Cryptography/CryptoConfig_2_1.cs +System.Security.Cryptography/CryptoConfig.fullaot.cs System.Security.Cryptography/CryptographicException.cs System.Security.Cryptography/CryptographicUnexpectedOperationExcpetion.cs System.Security.Cryptography/CryptoStream.cs diff --git a/mcs/class/reactive.pub b/mcs/class/reactive.pub new file mode 100644 index 00000000000..695f1b38774 Binary files /dev/null and b/mcs/class/reactive.pub differ diff --git a/mcs/docs/Makefile b/mcs/docs/Makefile index 3b653ccd692..79ad235c4e0 100644 --- a/mcs/docs/Makefile +++ b/mcs/docs/Makefile @@ -130,21 +130,21 @@ NUNIT_DIRS = \ netdocs.zip : netdocs.tree netdocs.tree: Makefile - $(MDOC) assemble -o netdocs $(NETDOCS_DIRS) + $(MDOC) --debug assemble -o netdocs $(NETDOCS_DIRS) Mono.zip : Mono.tree Mono.tree: Makefile - $(MDOC) assemble -o Mono $(MONO_DIRS) + $(MDOC) --debug assemble -o Mono $(MONO_DIRS) Novell.zip : Novell.tree Novell.tree: Makefile - $(MDOC) assemble -o Novell $(NOVELL_DIRS) + $(MDOC) --debug assemble -o Novell $(NOVELL_DIRS) cs-errors.zip : cs-errors.tree cs-errors.tree: cs-errors.config Makefile - $(MDOC) assemble -o cs-errors -f error $< + $(MDOC) --debug assemble -o cs-errors -f error $< ecma334.zip : ecma334.tree ecma334.tree: Makefile - $(MDOC) assemble -o ecma334 -f ecmaspec ecma334 + $(MDOC) --debug assemble -o ecma334 -f ecmaspec ecma334 diff --git a/mcs/errors/CS0012-17-lib.il b/mcs/errors/CS0012-17-lib.il new file mode 100644 index 00000000000..3dc2f90f306 --- /dev/null +++ b/mcs/errors/CS0012-17-lib.il @@ -0,0 +1,31 @@ +.assembly extern mscorlib +{ +} + +.assembly extern 'CS0012-lib-missing' +{ +} + +.assembly 'CS0012-17-lib' +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} + +.module 'CS0012-17-lib.dll' + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .method public hidebysig static void Foo<(class ['CS0012-lib-missing']AA`1) T>() cil managed + { + ret + } + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ret + } + +} diff --git a/mcs/errors/CS0012-18-lib.il b/mcs/errors/CS0012-18-lib.il new file mode 100644 index 00000000000..7305e5e2f07 --- /dev/null +++ b/mcs/errors/CS0012-18-lib.il @@ -0,0 +1,30 @@ +.assembly extern mscorlib +{ +} + +.assembly extern 'CS0012-lib-missing' +{ +} + +.assembly 'CS0012-18-lib' +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} + +.module 'CS0012-18-lib.dll' + + +.class public auto ansi beforefieldinit B + extends [mscorlib]System.Object +{ + .field public static literal valuetype ['CS0012-lib-missing']E e = int32(0x00000001) + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ret + } + +} + diff --git a/mcs/errors/CS1070-lib.il b/mcs/errors/CS1070-lib.il new file mode 100644 index 00000000000..d4487ff8443 --- /dev/null +++ b/mcs/errors/CS1070-lib.il @@ -0,0 +1,26 @@ +.assembly extern mscorlib +{ +} + +.assembly extern 'CS1070-lib-missing' +{ +} + +.assembly 'CS1070-lib' +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} + +.module 'CS1070-lib.dll' + +.class extern forwarder E +{ + .assembly extern 'CS1070-lib-missing' +} + +.class extern forwarder C +{ + .assembly extern 'CS1070-lib-missing' +} + diff --git a/mcs/errors/Makefile b/mcs/errors/Makefile index 96085dde45b..fccf2d93aa3 100644 --- a/mcs/errors/Makefile +++ b/mcs/errors/Makefile @@ -21,7 +21,7 @@ DISTFILES = \ $(wildcard dlls/second/*.cs) TEST_SUPPORT_FILES = \ - CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0029-26-lib.dll \ + CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0029-26-lib.dll \ CS0103-2-lib.dll CS0118-2-lib.dll CS0122-8-lib.dll CS0122-10-lib.dll CS0122-14-lib.dll CS0122-15-lib.dll CS0122-19-lib.dll CS0122-35-lib.dll CS0122-36-lib.dll CS0143-lib.dll CS0144-3-lib.dll CS0165-19-lib.dll \ CS0205-3-lib.dll CS0229-3-lib.dll CS0229-4-lib.dll CS0266-25-lib.dll \ CS0315-2-lib.dll \ @@ -30,6 +30,7 @@ TEST_SUPPORT_FILES = \ CS0612-2-lib.dll CS0618-2-lib.dll CS0619-8-lib.dll CS0619-17-lib.dll CS0619-32-lib.dll CS0619-33-lib.dll CS0619-36-lib.dll CS0619-42-lib.dll \ CS0619-43-lib.dll CS1546-lib.dll CS0619-51-lib.dll CS1509-module.dll CS1681-2-lib.dll \ CS0730-lib.dll \ + CS1070-lib.dll \ CS1540-15-lib.dll CS1540-17-lib.dll CS1542-lib.dll CS1577-lib.dll \ CS1607-3-lib.dll CS1683-lib.dll CS1684-lib.dll CS1685-2-lib.dll \ dlls/first/CS1701-lib.dll dlls/second/CS1701-lib.dll CS1701-lib.dll dlls/first/CS1702-lib.dll dlls/second/CS1702-lib.dll CS1702-lib.dll dlls/first/CS1705-lib.dll dlls/second/CS1705-lib.dll CS1705-lib.dll \ diff --git a/mcs/errors/cs0012-17.cs b/mcs/errors/cs0012-17.cs new file mode 100644 index 00000000000..a5df8bd94c9 --- /dev/null +++ b/mcs/errors/cs0012-17.cs @@ -0,0 +1,11 @@ +// CS0012: The type `AA`1' is defined in an assembly that is not referenced. Consider adding a reference to assembly `CS0012-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' +// Line: 9 +// Compiler options: -r:CS0012-17-lib.dll + +class Test +{ + public static void Main () + { + B.Foo (); + } +} diff --git a/mcs/errors/cs0012-18.cs b/mcs/errors/cs0012-18.cs new file mode 100644 index 00000000000..71395f3f19c --- /dev/null +++ b/mcs/errors/cs0012-18.cs @@ -0,0 +1,11 @@ +// CS0012: The type `E' is defined in an assembly that is not referenced. Consider adding a reference to assembly `CS0012-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' +// Line: 9 +// Compiler options: -r:CS0012-18-lib.dll + +class Test +{ + public static void Main () + { + var c = B.e; + } +} diff --git a/mcs/errors/cs0135-7.cs b/mcs/errors/cs0135-7.cs new file mode 100644 index 00000000000..4a61197c11d --- /dev/null +++ b/mcs/errors/cs0135-7.cs @@ -0,0 +1,22 @@ +// CS0135: `x' conflicts with a declaration in a child block +// Line: 18 + +public class Test +{ + Test x; + + void Foo () + { + { + string x = "dd"; + } + + { + x = null; + } + + x = new Test (); + } + + public static void Main () { } +} \ No newline at end of file diff --git a/mcs/errors/cs0214-16.cs b/mcs/errors/cs0214-16.cs new file mode 100644 index 00000000000..8d4a6640563 --- /dev/null +++ b/mcs/errors/cs0214-16.cs @@ -0,0 +1,9 @@ +// CS0214: Pointers and fixed size buffers may only be used in an unsafe context +// Line: 8 + +public class G {} + +abstract class A +{ + public abstract G Foo1 (); +} diff --git a/mcs/errors/cs0572-2.cs b/mcs/errors/cs0572-2.cs index f420cd9c8a7..cf09dfcaa37 100644 --- a/mcs/errors/cs0572-2.cs +++ b/mcs/errors/cs0572-2.cs @@ -1,4 +1,4 @@ -// CS0572: `meth': cannot reference a type through an expression; try `test.meth' instead +// CS0572: `meth': cannot reference a type through an expression. Consider using `test.meth' instead // Line: 8 class test2 : test { diff --git a/mcs/errors/cs0572-3.cs b/mcs/errors/cs0572-3.cs new file mode 100644 index 00000000000..675fd7dd6b6 --- /dev/null +++ b/mcs/errors/cs0572-3.cs @@ -0,0 +1,20 @@ +// CS0572: `Inner': cannot reference a type through an expression. Consider using `Outer.Inner' instead +// Line: 18 + +public class Outer +{ + public enum Inner + { + ONE, + TWO + } +} + +public class C +{ + public static bool Test () + { + Outer outer = null; + return 0 == outer.Inner.ONE; + } +} \ No newline at end of file diff --git a/mcs/errors/cs0572.cs b/mcs/errors/cs0572.cs index 01e7a62691f..a40ddfbddbb 100644 --- a/mcs/errors/cs0572.cs +++ b/mcs/errors/cs0572.cs @@ -1,4 +1,4 @@ -// CS0572: `Foo': cannot reference a type through an expression; try `Y.Foo' instead +// CS0572: `Foo': cannot reference a type through an expression. Consider using `Y.Foo' instead // Line: 13 using System; diff --git a/mcs/errors/cs1070.cs b/mcs/errors/cs1070.cs new file mode 100644 index 00000000000..30a51e4204f --- /dev/null +++ b/mcs/errors/cs1070.cs @@ -0,0 +1,7 @@ +// CS1070: The type `C' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `CS1070-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' +// Line: 5 +// Compiler options: -r:CS1070-lib.dll + +public class D : C +{ +} \ No newline at end of file diff --git a/mcs/ilasm/codegen/ExternTable.cs b/mcs/ilasm/codegen/ExternTable.cs index ff0237d8398..25a46efbf31 100644 --- a/mcs/ilasm/codegen/ExternTable.cs +++ b/mcs/ilasm/codegen/ExternTable.cs @@ -9,9 +9,11 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Security; using System.Globalization; +using PEAPI; namespace Mono.ILASM { @@ -247,11 +249,34 @@ namespace Mono.ILASM { } + public class ExternClass + { + string name; + TypeAttr ta; + string assemblyReference; + + public ExternClass (string name, TypeAttr ta, string assemblyReference) + { + this.name = name; + this.ta = ta; + this.assemblyReference = assemblyReference; + } + + public void Resolve (CodeGen code_gen, ExternTable table) + { + var ar = table.GetAssemblyRef (assemblyReference); + if (ar != null) + code_gen.PEFile.AddExternClass (name, ta, ar.AssemblyRef); + } + } + public class ExternTable { Hashtable assembly_table; Hashtable module_table; + List class_table; + bool is_resolved; public void AddCorlib () @@ -305,6 +330,14 @@ namespace Mono.ILASM { return em; } + public void AddClass (string name, TypeAttr ta, string assemblyReference) + { + if (class_table == null) + class_table = new List (); + + class_table.Add (new ExternClass (name, ta, assemblyReference)); + } + public void Resolve (CodeGen code_gen) { if (is_resolved) @@ -313,12 +346,16 @@ namespace Mono.ILASM { if (assembly_table != null) foreach (ExternAssembly ext in assembly_table.Values) ext.Resolve (code_gen); - if (module_table == null) - return; - foreach (ExternModule ext in module_table.Values) - ext.Resolve (code_gen); - is_resolved = true; + if (module_table != null) + foreach (ExternModule ext in module_table.Values) + ext.Resolve (code_gen); + + if (class_table != null) + foreach (var entry in class_table) + entry.Resolve (code_gen, this); + + is_resolved = true; } public ExternTypeRef GetTypeRef (string asmb_name, string full_name, bool is_valuetype) @@ -356,6 +393,18 @@ namespace Mono.ILASM { return mod.GetTypeRef (full_name, is_valuetype); } + public ExternAssembly GetAssemblyRef (string assembly_name) + { + ExternAssembly ass = null; + if (assembly_table != null) + ass = assembly_table [assembly_name] as ExternAssembly; + + if (ass == null) + Report.Error ("Assembly " + assembly_name + " is not defined."); + + return ass; + } + public static void GetNameAndNamespace (string full_name, out string name_space, out string name) { diff --git a/mcs/ilasm/parser/ILParser.jay b/mcs/ilasm/parser/ILParser.jay index 523c5ffe1a2..19a567e0ca5 100644 --- a/mcs/ilasm/parser/ILParser.jay +++ b/mcs/ilasm/parser/ILParser.jay @@ -10,6 +10,7 @@ using PEAPI; using System; using System.IO; using System.Collections; +using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Security; @@ -32,6 +33,7 @@ namespace Mono.ILASM { private PEAPI.PInvokeAttr pinvoke_attr; private ILTokenizer tokenizer; static int yacc_verbose_flag; + KeyValuePair current_extern; class NameValuePair { public string Name; @@ -476,6 +478,7 @@ namespace Mono.ILASM { %token K_IS %token K_ON %token K_OFF +%token K_FORWARDER %token K_CHARMAPERROR /* end generated */ @@ -3201,17 +3204,21 @@ exptype_all : exptype_head OPEN_BRACE exptype_decls CLOSE_BRACE ; exptype_head : D_CLASS K_EXTERN expt_attr comp_name + { + current_extern = new KeyValuePair ((string) $4, (TypeAttr) $3); + } ; expt_attr : /* EMPTY */ - | expt_attr K_PRIVATE - | expt_attr K_PUBLIC - | expt_attr K_NESTED K_PUBLIC - | expt_attr K_NESTED K_PRIVATE - | expt_attr K_NESTED K_FAMILY - | expt_attr K_NESTED K_ASSEMBLY - | expt_attr K_NESTED K_FAMANDASSEM - | expt_attr K_NESTED K_FAMORASSEM + | expt_attr K_PRIVATE { $$ = (TypeAttr)$1 | TypeAttr.Private; } + | expt_attr K_PUBLIC { $$ = (TypeAttr)$1 | TypeAttr.Public; } + | expt_attr K_NESTED K_PUBLIC { $$ = (TypeAttr)$1 | TypeAttr.NestedPublic; } + | expt_attr K_NESTED K_PRIVATE { $$ = (TypeAttr)$1 | TypeAttr.NestedPrivate; } + | expt_attr K_NESTED K_FAMILY { $$ = (TypeAttr)$1 | TypeAttr.NestedFamily; } + | expt_attr K_NESTED K_ASSEMBLY { $$ = (TypeAttr)$1 | TypeAttr.NestedAssembly;} + | expt_attr K_NESTED K_FAMANDASSEM { $$ = (TypeAttr)$1 | TypeAttr.NestedFamAndAssem; } + | expt_attr K_NESTED K_FAMORASSEM { $$ = (TypeAttr)$1 | TypeAttr.NestedFamOrAssem; } + | K_FORWARDER { $$ = TypeAttr.Forwarder; } ; exptype_decls : /* EMPTY */ @@ -3220,8 +3227,11 @@ exptype_decls : /* EMPTY */ exptype_decl : D_FILE comp_name | D_CLASS K_EXTERN comp_name - | D_CLASS int32 | customattr_decl + | D_ASSEMBLY K_EXTERN comp_name + { + codegen.ExternTable.AddClass (current_extern.Key, current_extern.Value, (string) $3); + } ; manifestres_all : manifestres_head OPEN_BRACE manifestres_decls CLOSE_BRACE diff --git a/mcs/ilasm/scanner/ILTables.cs b/mcs/ilasm/scanner/ILTables.cs index 42f2d1aa8c7..deb2f3a7ba3 100644 --- a/mcs/ilasm/scanner/ILTables.cs +++ b/mcs/ilasm/scanner/ILTables.cs @@ -318,6 +318,7 @@ namespace Mono.ILASM { keywords ["on"] = new ILToken (Token.K_ON, "on"); keywords ["off"] = new ILToken (Token.K_OFF, "off"); keywords ["strict"] = new ILToken (Token.K_STRICT, "strict"); + keywords ["forwarder"] = new ILToken (Token.K_FORWARDER, "forwarder"); return keywords; } diff --git a/mcs/mcs/Makefile b/mcs/mcs/Makefile index e45aeb008f9..bc52a7bcdeb 100644 --- a/mcs/mcs/Makefile +++ b/mcs/mcs/Makefile @@ -22,7 +22,7 @@ the_libdir = $(topdir)/class/lib/build/ LOCAL_MCS_FLAGS += -lib:$(topdir)/class/lib/build -debug endif -LOCAL_MCS_FLAGS += -d:STATIC,NO_SYMBOL_WRITER +LOCAL_MCS_FLAGS += -d:STATIC,NO_SYMBOL_WRITER,NO_AUTHENTICODE PROGRAM_INSTALL_DIR = $(mono_libdir)/mono/4.5 diff --git a/mcs/mcs/assembly.cs b/mcs/mcs/assembly.cs index f95a4d3cfa1..0124ce91641 100644 --- a/mcs/mcs/assembly.cs +++ b/mcs/mcs/assembly.cs @@ -36,7 +36,6 @@ namespace Mono.CSharp public interface IAssemblyDefinition { string FullName { get; } - bool HasExtensionMethod { get; } bool IsCLSCompliant { get; } bool IsMissing { get; } string Name { get; } @@ -132,12 +131,6 @@ namespace Mono.CSharp } } - public bool HasExtensionMethod { - get { - return module.HasExtensionMethod; - } - } - public bool HasCLSCompliantAttribute { get { return cls_attribute != null; diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index 95a628e102d..b335e09f348 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -670,6 +670,12 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + // // Returns true for secondary partial containers // diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs index 7fee671c12d..189bdea6f55 100644 --- a/mcs/mcs/cs-tokenizer.cs +++ b/mcs/mcs/cs-tokenizer.cs @@ -1251,6 +1251,7 @@ namespace Mono.CSharp case Token.OPEN_BRACKET: case Token.OP_GENERICS_GT: case Token.INTERR: + case Token.OP_COALESCING: next_token = Token.INTERR_NULLABLE; break; diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index 47d4971197c..f035ba65525 100644 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -966,7 +966,10 @@ namespace Mono.CSharp { this.definition = definition; this.modifiers = modifiers; - state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected; + if (kind == MemberKind.MissingType) + state = StateFlags.MissingDependency; + else + state = StateFlags.Obsolete_Undetected | StateFlags.CLSCompliant_Undetected | StateFlags.MissingDependency_Undetected; } #region Properties diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 2c434e3a082..e990acb244e 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -360,6 +360,27 @@ namespace Mono.CSharp { } } + // + // Implements identical simple name and type-name resolution + // + public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name) + { + var t = left.Type; + if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0) + return left; + + // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is + // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name + + if (left is MemberExpr || left is VariableReference) { + var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr; + if (identical_type != null && identical_type.Type == left.Type) + return identical_type; + } + + return left; + } + public virtual string GetSignatureForError () { return type.GetDefinition ().GetSignatureForError (); @@ -2783,7 +2804,7 @@ namespace Mono.CSharp { // TypeSpec[] targs = null; if (method.DeclaringType != InstanceExpression.Type) { - var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly) as MethodSpec; + var base_override = MemberCache.FindMember (InstanceExpression.Type, new MemberFilter (method), BindingRestriction.InstanceOnly | BindingRestriction.OverrideOnly) as MethodSpec; if (base_override != null && base_override.DeclaringType != method.DeclaringType) { if (base_override.IsGeneric) targs = method.TypeArguments; @@ -2928,27 +2949,6 @@ namespace Mono.CSharp { member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ()); } - // - // Implements identicial simple name and type-name - // - public Expression ProbeIdenticalTypeName (ResolveContext rc, Expression left, SimpleName name) - { - var t = left.Type; - if (t.Kind == MemberKind.InternalCompilerType || t is ElementTypeSpec || t.Arity > 0) - return left; - - // In a member access of the form E.I, if E is a single identifier, and if the meaning of E as a simple-name is - // a constant, field, property, local variable, or parameter with the same type as the meaning of E as a type-name - - if (left is MemberExpr || left is VariableReference) { - var identical_type = rc.LookupNamespaceOrType (name.Name, 0, LookupMode.Probing, loc) as TypeExpr; - if (identical_type != null && identical_type.Type == left.Type) - return identical_type; - } - - return left; - } - public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs) { if (!ResolveInstanceExpressionCore (rc, rhs)) @@ -3822,11 +3822,7 @@ namespace Mono.CSharp { // better conversion is performed between underlying types Y1 and Y2 // if (p.IsGenericTask || q.IsGenericTask) { - if (am.Block.IsAsync) { - if (p.IsGenericTask != q.IsGenericTask) { - return 0; - } - + if (am.Block.IsAsync && p.IsGenericTask && q.IsGenericTask) { q = q.TypeArguments[0]; p = p.TypeArguments[0]; } @@ -4200,6 +4196,9 @@ namespace Mono.CSharp { } else if (arg_count > param_count) { int args_gap = System.Math.Abs (arg_count - param_count); return int.MaxValue - 10000 + args_gap; + } else if (arg_count < param_count - optional_count) { + int args_gap = System.Math.Abs (param_count - optional_count - arg_count); + return int.MaxValue - 10000 + args_gap; } } else if (arg_count != param_count) { int args_gap = System.Math.Abs (arg_count - param_count); @@ -4402,34 +4401,8 @@ namespace Mono.CSharp { // if the type matches // Expression e = fp.DefaultValue; - if (!(e is Constant) || e.Type != ptypes [i]) { - // - // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null - // - var ptype = ptypes [i]; - if (e == EmptyExpression.MissingValue && ptype.BuiltinType == BuiltinTypeSpec.Type.Object || ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { - e = new MemberAccess (new MemberAccess (new MemberAccess ( - new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc); - } else if (e is Constant) { - // - // Handles int to int? conversions - // - e = Convert.ImplicitConversionStandard (ec, e, ptype, loc); - - // - // When constant type paramter contains type argument - // - // Foo (T[] arg = null) - // - if (e == null) { - e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc); - } - } else { - e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc); - } - - - e = e.Resolve (ec); + if (e != null) { + e = ResolveDefaultValueArgument (ec, ptypes[i], e, loc); } if ((fp.ModFlags & Parameter.Modifier.CallerMask) != 0) { @@ -4522,6 +4495,39 @@ namespace Mono.CSharp { return 0; } + public static Expression ResolveDefaultValueArgument (ResolveContext ec, TypeSpec ptype, Expression e, Location loc) + { + if (e is Constant && e.Type == ptype) + return e; + + // + // LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null + // + if (e == EmptyExpression.MissingValue && ptype.BuiltinType == BuiltinTypeSpec.Type.Object || ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { + e = new MemberAccess (new MemberAccess (new MemberAccess ( + new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Reflection", loc), "Missing", loc), "Value", loc); + } else if (e is Constant) { + // + // Handles int to int? conversions + // + e = Convert.ImplicitConversionStandard (ec, e, ptype, loc); + + // + // When constant type paramter contains type argument + // + // Foo (T[] arg = null) + // + if (e == null) { + e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc); + } + } else { + e = new DefaultValueExpression (new TypeExpression (ptype, loc), loc); + } + + + return e.Resolve (ec); + } + // // Tests argument compatibility with the parameter // The possible return values are @@ -5812,6 +5818,8 @@ namespace Mono.CSharp { // sealed class PropertyExpr : PropertyOrIndexerExpr { + Arguments arguments; + public PropertyExpr (PropertySpec spec, Location l) : base (l) { @@ -5823,9 +5831,10 @@ namespace Mono.CSharp { protected override Arguments Arguments { get { - return null; + return arguments; } set { + arguments = value; } } @@ -5982,7 +5991,7 @@ namespace Mono.CSharp { } } } else { - args = new Arguments (1); + args = arguments == null ? new Arguments (1) : arguments; if (leave_copy) { source.Emit (ec); @@ -6032,6 +6041,22 @@ namespace Mono.CSharp { } DoBestMemberChecks (rc, best_candidate); + + // Handling of com-imported properties with any number of default property parameters + if (best_candidate.HasGet && !best_candidate.Get.Parameters.IsEmpty) { + var p = best_candidate.Get.Parameters; + arguments = new Arguments (p.Count); + for (int i = 0; i < p.Count; ++i) { + arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc))); + } + } else if (best_candidate.HasSet && best_candidate.Set.Parameters.Count > 1) { + var p = best_candidate.Set.Parameters; + arguments = new Arguments (p.Count - 1); + for (int i = 0; i < p.Count - 1; ++i) { + arguments.Add (new Argument (OverloadResolver.ResolveDefaultValueArgument (rc, p.Types [i], p.FixedParameters [i].DefaultValue, loc))); + } + } + return this; } diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 9001763a268..fd501dff633 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -4643,7 +4643,7 @@ namespace Mono.CSharp // ambiguous because 1 literal can be converted to short. // if (conv_false_expr != null) { - if (conv_false_expr is IntConstant && conv is Constant) { + if (conv_false_expr.Type.BuiltinType == BuiltinTypeSpec.Type.Int && conv is Constant) { type = true_type; conv_false_expr = null; } else if (type.BuiltinType == BuiltinTypeSpec.Type.Int && conv_false_expr is Constant) { @@ -8064,13 +8064,9 @@ namespace Mono.CSharp TypeExpr texpr = member_lookup as TypeExpr; if (texpr != null) { - if (!(expr is TypeExpr)) { - me = expr as MemberExpr; - if (me == null || me.ProbeIdenticalTypeName (rc, expr, sn) == expr) { - rc.Report.Error (572, loc, "`{0}': cannot reference a type through an expression; try `{1}' instead", - Name, member_lookup.GetSignatureForError ()); - return null; - } + if (!(expr is TypeExpr) && (sn == null || expr.ProbeIdenticalTypeName (rc, expr, sn) == expr)) { + rc.Report.Error (572, loc, "`{0}': cannot reference a type through an expression. Consider using `{1}' instead", + Name, texpr.GetSignatureForError ()); } if (!texpr.Type.IsAccessible (rc)) { diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index 57c7ac96cd7..91eeadc7515 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -416,6 +416,12 @@ namespace Mono.CSharp { } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool ITypeDefinition.IsPartial { get { return false; @@ -428,6 +434,12 @@ namespace Mono.CSharp { } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public string Name { get { return MemberName.Name; @@ -1250,6 +1262,22 @@ namespace Mono.CSharp { return false; } + public bool HasDependencyOn (TypeSpec type) + { + if (TypeArguments != null) { + foreach (var targ in TypeArguments) { + if (TypeSpecComparer.Override.IsEqual (targ, type)) + return true; + + var tps = targ as TypeParameterSpec; + if (tps != null && tps.HasDependencyOn (type)) + return true; + } + } + + return false; + } + public override TypeSpec Mutate (TypeParameterMutator mutator) { return mutator.Mutate (this); @@ -2422,12 +2450,8 @@ namespace Mono.CSharp { if (atype.IsGenericParameter) { var tps = (TypeParameterSpec) atype; - if (tps.TypeArguments != null) { - foreach (var targ in tps.TypeArguments) { - if (TypeSpecComparer.Override.IsEqual (targ, ttype)) - return true; - } - } + if (tps.HasDependencyOn (ttype)) + return true; if (Convert.ImplicitTypeParameterConversion (null, tps, ttype) != null) return true; diff --git a/mcs/mcs/ikvm.cs b/mcs/mcs/ikvm.cs index 55b66a589c5..2f234e01e54 100644 --- a/mcs/mcs/ikvm.cs +++ b/mcs/mcs/ikvm.cs @@ -93,10 +93,15 @@ namespace Mono.CSharp { // It can be used more than once when importing same assembly // into 2 or more global aliases - var definition = GetAssemblyDefinition (assembly); + // TODO: Should be just Add + GetAssemblyDefinition (assembly); var all_types = assembly.GetTypes (); - ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod); + ImportTypes (all_types, targetNamespace, true); + + all_types = assembly.ManifestModule.__GetExportedTypes (); + if (all_types.Length != 0) + ImportForwardedTypes (all_types, targetNamespace); } public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace) @@ -110,6 +115,31 @@ namespace Mono.CSharp return module_definition; } + void ImportForwardedTypes (MetaType[] types, Namespace targetNamespace) + { + Namespace ns = targetNamespace; + string prev_namespace = null; + foreach (var t in types) { + // IsMissing tells us the type has been forwarded and target assembly is missing + if (!t.__IsMissing) + continue; + + if (t.Name[0] == '<') + continue; + + var it = CreateType (t, null, new DynamicTypeReader (t), true); + if (it == null) + continue; + + if (prev_namespace != t.Namespace) { + ns = t.Namespace == null ? targetNamespace : targetNamespace.GetNamespace (t.Namespace, true); + prev_namespace = t.Namespace; + } + + ns.AddType (module, it); + } + } + public void InitializeBuiltinTypes (BuiltinTypes builtin, Assembly corlib) { // @@ -545,7 +575,7 @@ namespace Mono.CSharp public override void SetFlags (uint flags, Location loc) { - builder.__SetAssemblyFlags ((AssemblyNameFlags) flags); + builder.__AssemblyFlags = (AssemblyNameFlags) flags; } public override void SetVersion (Version version, Location loc) @@ -553,4 +583,4 @@ namespace Mono.CSharp builder.__SetAssemblyVersion (version); } } -} \ No newline at end of file +} diff --git a/mcs/mcs/import.cs b/mcs/mcs/import.cs index f8c7bb8bf55..8474e29a5b4 100644 --- a/mcs/mcs/import.cs +++ b/mcs/mcs/import.cs @@ -6,7 +6,7 @@ // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2009-2011 Novell, Inc -// Copyright 2011 Xamarin, Inc (http://www.xamarin.com) +// Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) // using System; @@ -32,7 +32,7 @@ namespace Mono.CSharp // Dynamic types reader with additional logic to reconstruct a dynamic // type using DynamicAttribute values // - struct DynamicTypeReader + protected struct DynamicTypeReader { static readonly bool[] single_attribute = { true }; @@ -120,7 +120,7 @@ namespace Mono.CSharp protected readonly Dictionary import_cache; protected readonly Dictionary compiled_types; protected readonly Dictionary assembly_2_definition; - readonly ModuleContainer module; + protected readonly ModuleContainer module; public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices"; @@ -191,7 +191,9 @@ namespace Mono.CSharp var definition = new ImportedMemberDefinition (fi, field_type, this); if ((fa & FieldAttributes.Literal) != 0) { - var c = Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null); + Constant c = field_type.Kind == MemberKind.MissingType ? + new NullConstant (InternalType.ErrorType, Location.Null) : + Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null); return new ConstSpec (declaringType, definition, field_type, fi, mod, c); } @@ -489,7 +491,7 @@ namespace Mono.CSharp // var el = p.ParameterType.GetElementType (); types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible - } else if (i == 0 && method.IsStatic && parent.IsStatic && parent.MemberDefinition.DeclaringAssembly.HasExtensionMethod && + } else if (i == 0 && method.IsStatic && (parent.Modifiers & Modifiers.METHOD_EXTENSION) != 0 && HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) { mod = Parameter.Modifier.This; types[i] = ImportType (p.ParameterType); @@ -618,26 +620,41 @@ namespace Mono.CSharp PropertySpec spec = null; if (!param.IsEmpty) { - var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); - if (index_name == null) { - is_valid_property = false; - } else { - if (get != null) { - if (get.IsStatic) - is_valid_property = false; - if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) - is_valid_property = false; + if (is_valid_property) { + var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); + if (index_name == null) { + is_valid_property = false; + } else { + if (get != null) { + if (get.IsStatic) + is_valid_property = false; + if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) + is_valid_property = false; + } + if (set != null) { + if (set.IsStatic) + is_valid_property = false; + if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) + is_valid_property = false; + } } - if (set != null) { - if (set.IsStatic) - is_valid_property = false; - if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) - is_valid_property = false; + + if (is_valid_property) { + spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); + } else if (declaringType.MemberDefinition.IsComImport && param.FixedParameters[0].HasDefaultValue) { + // + // Enables support for properties with parameters (must have default value) of COM-imported types + // + is_valid_property = true; + + for (int i = 0; i < param.FixedParameters.Length; ++i) { + if (!param.FixedParameters[i].HasDefaultValue) { + is_valid_property = false; + break; + } + } } } - - if (is_valid_property) - spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); } if (spec == null) @@ -677,7 +694,7 @@ namespace Mono.CSharp return CreateType (type, declaring_type, dtype, canImportBaseType); } - TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType) + protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType) { TypeSpec spec; if (import_cache.TryGetValue (type, out spec)) { @@ -1028,7 +1045,7 @@ namespace Mono.CSharp } } - protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes) + protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes) { Namespace ns = targetNamespace; string prev_namespace = null; @@ -1052,12 +1069,14 @@ namespace Mono.CSharp prev_namespace = t.Namespace; } - ns.AddType (module, it); - - if (it.IsStatic && hasExtensionTypes && + // Cannot rely on assembly level Extension attribute or static modifier because they + // are not followed by other compilers (e.g. F#). + if (it.IsClass && it.Arity == 0 && importExtensionTypes && HasAttribute (CustomAttributeData.GetCustomAttributes (t), "ExtensionAttribute", CompilerServicesNamespace)) { it.SetExtensionMethodContainer (); } + + ns.AddType (module, it); } } @@ -1074,12 +1093,13 @@ namespace Mono.CSharp continue; } - if (!IsMissingType (ct) && ct.IsClass) { - spec.BaseType = CreateType (ct); + var constraint_type = CreateType (ct); + if (constraint_type.IsClass) { + spec.BaseType = constraint_type; continue; } - spec.AddInterface (CreateType (ct)); + spec.AddInterface (constraint_type); } if (spec.BaseType == null) @@ -1520,7 +1540,6 @@ namespace Mono.CSharp readonly Assembly assembly; readonly AssemblyName aname; bool cls_compliant; - bool contains_extension_methods; List internals_visible_to; Dictionary internals_visible_to_cache; @@ -1545,12 +1564,6 @@ namespace Mono.CSharp } } - public bool HasExtensionMethod { - get { - return contains_extension_methods; - } - } - public bool HasStrongName { get { return aname.GetPublicKey ().Length != 0; @@ -1668,13 +1681,6 @@ namespace Mono.CSharp internals_visible_to.Add (an); continue; } - - if (name == "ExtensionAttribute") { - if (dt.Namespace == MetadataImporter.CompilerServicesNamespace) - contains_extension_methods = true; - - continue; - } } } @@ -1777,12 +1783,29 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return ((MetaType) provider).IsImport; + } + } + + bool ITypeDefinition.IsPartial { get { return false; } } + bool ITypeDefinition.IsTypeForwarder { + get { +#if STATIC + return ((MetaType) provider).__IsTypeForwarder; +#else + return false; +#endif + } + } + public override string Name { get { if (name == null) { @@ -1845,9 +1868,15 @@ namespace Mono.CSharp "Reference to type `{0}' claims it is defined in this assembly, but it is not defined in source or any added modules", name); } else if (t.MemberDefinition.DeclaringAssembly.IsMissing) { - ctx.Module.Compiler.Report.Error (12, loc, - "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'", - name, t.MemberDefinition.DeclaringAssembly.FullName); + if (t.MemberDefinition.IsTypeForwarder) { + ctx.Module.Compiler.Report.Error (1070, loc, + "The type `{0}' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `{1}'", + name, t.MemberDefinition.DeclaringAssembly.FullName); + } else { + ctx.Module.Compiler.Report.Error (12, loc, + "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'", + name, t.MemberDefinition.DeclaringAssembly.FullName); + } } else { ctx.Module.Compiler.Report.Error (1684, loc, "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found", @@ -2122,12 +2151,24 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool ITypeDefinition.IsPartial { get { return false; } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public string Namespace { get { return null; diff --git a/mcs/mcs/mcs.csproj b/mcs/mcs/mcs.csproj index 9f9d00e4a07..74609d1947e 100644 --- a/mcs/mcs/mcs.csproj +++ b/mcs/mcs/mcs.csproj @@ -18,7 +18,7 @@ full False . - TRACE;DEBUG;NET_4_0;STATIC;NO_SYMBOL_WRITER + TRACE;DEBUG;NET_4_0;STATIC;NO_SYMBOL_WRITER;NO_AUTHENTICODE prompt 4 false @@ -26,7 +26,7 @@ pdbonly True - TRACE;NET_4_0;STATIC;NO_SYMBOL_WRITER + TRACE;NET_4_0;STATIC;NO_SYMBOL_WRITER;NO_AUTHENTICODE prompt prompt 4 @@ -35,7 +35,7 @@ True . - TRACE;DEBUG;NET_4_0;STATIC;NO_SYMBOL_WRITER;FULL_AST + TRACE;DEBUG;NET_4_0;STATIC;NO_SYMBOL_WRITER;NO_AUTHENTICODE;FULL_AST full mcs.exe.CodeAnalysisLog.xml true @@ -158,34 +158,34 @@ - + False - + False - + False - + False - + False - + False - + False - \ No newline at end of file diff --git a/mcs/mcs/mcs.exe.sources b/mcs/mcs/mcs.exe.sources index 7acf63aeff2..9ac9cb1c1ad 100644 --- a/mcs/mcs/mcs.exe.sources +++ b/mcs/mcs/mcs.exe.sources @@ -57,10 +57,10 @@ visit.cs ../build/common/Consts.cs ../tools/monop/outline.cs -../class/IKVM.Reflection/*.cs -../class/IKVM.Reflection/Emit/*.cs -../class/IKVM.Reflection/Metadata/*.cs -../class/IKVM.Reflection/Reader/*.cs -../class/IKVM.Reflection/Writer/*.cs -../class/IKVM.Reflection/Impl/ITypeOwner.cs -../class/IKVM.Reflection/Impl/SymbolSupport.cs +../../external/ikvm/reflect/*.cs +../../external/ikvm/reflect/Emit/*.cs +../../external/ikvm/reflect/Metadata/*.cs +../../external/ikvm/reflect/Reader/*.cs +../../external/ikvm/reflect/Writer/*.cs +../../external/ikvm/reflect/Impl/ITypeOwner.cs +../../external/ikvm/reflect/Impl/SymbolSupport.cs diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs index 9ff3168869e..c2d9a630a3a 100644 --- a/mcs/mcs/membercache.cs +++ b/mcs/mcs/membercache.cs @@ -302,7 +302,7 @@ namespace Mono.CSharp { // rules (e.g. binary operators) by not setting the flag we hide them for // user conversions // - if (!BuiltinTypeSpec.IsPrimitiveType (dt)) { + if (!BuiltinTypeSpec.IsPrimitiveType (dt) || dt.BuiltinType == BuiltinTypeSpec.Type.Char) { switch (dt.BuiltinType) { case BuiltinTypeSpec.Type.String: case BuiltinTypeSpec.Type.Delegate: diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs index 8e3e8d1da7c..c0fe77b268e 100644 --- a/mcs/mcs/method.cs +++ b/mcs/mcs/method.cs @@ -1779,7 +1779,7 @@ namespace Mono.CSharp { var token = ConstructorBuilder.GetToken (); int t = token.Token; #if STATIC - if (token.IsPseudoToken) + if (ModuleBuilder.IsPseudoToken (t)) t = Module.Builder.ResolvePseudoToken (t); #endif @@ -2120,7 +2120,7 @@ namespace Mono.CSharp { var token = builder.GetToken (); int t = token.Token; #if STATIC - if (token.IsPseudoToken) + if (ModuleBuilder.IsPseudoToken (t)) t = member.Module.Builder.ResolvePseudoToken (t); #endif diff --git a/mcs/mcs/namespace.cs b/mcs/mcs/namespace.cs index e87d59521c4..7dd44807f68 100644 --- a/mcs/mcs/namespace.cs +++ b/mcs/mcs/namespace.cs @@ -498,12 +498,14 @@ namespace Mono.CSharp { types = new Dictionary> (64); } - if ((ts.IsStatic || ts.MemberDefinition.IsPartial) && ts.Arity == 0 && - (ts.MemberDefinition.DeclaringAssembly == null || ts.MemberDefinition.DeclaringAssembly.HasExtensionMethod)) { - if (extension_method_types == null) - extension_method_types = new List (); + if (ts.IsClass && ts.Arity == 0) { + var extension_method_allowed = ts.MemberDefinition.IsImported ? (ts.Modifiers & Modifiers.METHOD_EXTENSION) != 0 : (ts.IsStatic || ts.MemberDefinition.IsPartial); + if (extension_method_allowed) { + if (extension_method_types == null) + extension_method_types = new List (); - extension_method_types.Add (ts); + extension_method_types.Add (ts); + } } var name = ts.Name; @@ -648,6 +650,11 @@ namespace Mono.CSharp { "Identifier `{0}' differing only in case is not CLS-compliant", compiled.GetSignatureForError ()); } } + + public override string ToString () + { + return Name; + } } public class CompilationSourceFile : NamespaceContainer @@ -1385,6 +1392,11 @@ namespace Mono.CSharp { } } } + + public override string ToString() + { + return resolved.ToString(); + } } public class UsingExternAlias : UsingAliasNamespace diff --git a/mcs/mcs/pending.cs b/mcs/mcs/pending.cs index fb59f1d016e..7684c117c04 100644 --- a/mcs/mcs/pending.cs +++ b/mcs/mcs/pending.cs @@ -548,7 +548,7 @@ namespace Mono.CSharp { continue; var candidate_param = ((MethodSpec) candidate).Parameters; - if (!TypeSpecComparer.Override.IsSame (parameters.Types, candidate_param.Types)) + if (!TypeSpecComparer.Override.IsEqual (parameters.Types, candidate_param.Types)) continue; bool modifiers_match = true; @@ -587,7 +587,7 @@ namespace Mono.CSharp { continue; // - // From this point on the candidate is used for detailed error reporting + // From this point the candidate is used for detailed error reporting // because it's very close match to what we are looking for // base_method = (MethodSpec) candidate; diff --git a/mcs/mcs/reflection.cs b/mcs/mcs/reflection.cs index 2de023c18fe..411416712ad 100644 --- a/mcs/mcs/reflection.cs +++ b/mcs/mcs/reflection.cs @@ -83,7 +83,7 @@ namespace Mono.CSharp { // It can be used more than once when importing same assembly // into 2 or more global aliases - var definition = GetAssemblyDefinition (assembly); + GetAssemblyDefinition (assembly); // // This part tries to simulate loading of top-level @@ -98,7 +98,7 @@ namespace Mono.CSharp all_types = e.Types; } - ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod); + ImportTypes (all_types, targetNamespace, true); } public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace) @@ -547,4 +547,4 @@ namespace Mono.CSharp } } } -} \ No newline at end of file +} diff --git a/mcs/mcs/settings.cs b/mcs/mcs/settings.cs index 1556b5ca5fa..af8512ae255 100644 --- a/mcs/mcs/settings.cs +++ b/mcs/mcs/settings.cs @@ -600,24 +600,7 @@ namespace Mono.CSharp { static bool IsExternAliasValid (string identifier) { - if (identifier.Length == 0) - return false; - if (identifier[0] != '_' && !char.IsLetter (identifier[0])) - return false; - - for (int i = 1; i < identifier.Length; i++) { - char c = identifier[i]; - if (char.IsLetter (c) || char.IsDigit (c)) - continue; - - UnicodeCategory category = char.GetUnicodeCategory (c); - if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark || - category != UnicodeCategory.SpacingCombiningMark || - category != UnicodeCategory.ConnectorPunctuation) - return false; - } - - return true; + return Tokenizer.IsValidIdentifier (identifier); } static string[] LoadArgs (string file) diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index 8337ce59b8d..d1e1b709d1d 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -1056,6 +1056,23 @@ namespace Mono.CSharp return true; } + public static bool IsEqual (TypeSpec[] a, TypeSpec[] b) + { + if (a == b) + return true; + + if (a.Length != b.Length) + return false; + + for (int i = 0; i < a.Length; ++i) { + if (!IsEqual (a[i], b[i])) + return false; + } + + return true; + } + + // // Compares unordered arrays // @@ -1337,6 +1354,8 @@ namespace Mono.CSharp IAssemblyDefinition DeclaringAssembly { get; } string Namespace { get; } bool IsPartial { get; } + bool IsComImport { get; } + bool IsTypeForwarder { get; } int TypeParametersCount { get; } TypeParameterSpec[] TypeParameters { get; } @@ -1384,6 +1403,12 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool IMemberDefinition.IsImported { get { return false; @@ -1396,6 +1421,12 @@ namespace Mono.CSharp } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public override string Name { get { return name; @@ -1508,12 +1539,24 @@ namespace Mono.CSharp public TypeSpec Element { get; private set; } + bool ITypeDefinition.IsComImport { + get { + return false; + } + } + bool ITypeDefinition.IsPartial { get { return false; } } + bool ITypeDefinition.IsTypeForwarder { + get { + return false; + } + } + public override string Name { get { throw new NotSupportedException (); diff --git a/mcs/tests/Makefile b/mcs/tests/Makefile index 2f967c8a0d2..3be0a849855 100644 --- a/mcs/tests/Makefile +++ b/mcs/tests/Makefile @@ -91,9 +91,5 @@ csproj-local: $(ILASM) /dll /out:$@ $< setup: - $(ILASM) /dll property-il.il - $(CSCOMPILE) /r:property-il.dll property-main.cs /out:property-main.exe - $(TEST_RUNTIME) property-main.exe - $(CSCOMPILE) -t:library dlls/test-679-2/test-679-lib-2.cs $(CSCOMPILE) -t:library dlls/test-679-1/test-679-lib.cs -r:dlls/test-679-2/test-679-lib-2.dll diff --git a/mcs/tests/gtest-409.cs b/mcs/tests/gtest-409.cs index a17f9c284ff..12f979cff36 100644 --- a/mcs/tests/gtest-409.cs +++ b/mcs/tests/gtest-409.cs @@ -106,6 +106,11 @@ public class ConditionalParsing return 1; } + void Test_13 (object param) + { + if (param as bool? ?? false) {} else {} + } + public static void Main () { } diff --git a/mcs/tests/gtest-571.cs b/mcs/tests/gtest-571.cs new file mode 100644 index 00000000000..75cd9a2a828 --- /dev/null +++ b/mcs/tests/gtest-571.cs @@ -0,0 +1,37 @@ +using System; + +public abstract class A +{ + public abstract A For () where MM : T; +} + +public class B : A + where V : X + where X : U +{ + readonly A _inner; + + public B (A inner) + { + _inner = inner; + } + + public override A For () // base constraint is copied as PP : V + { + return _inner.For (); + } +} + +public class Test : A +{ + public static void Main () + { + var t = new Test (); + new B (t).For (); + } + + public override A For () + { + return null; + } +} diff --git a/mcs/tests/gtest-exmethod-45-lib.il b/mcs/tests/gtest-exmethod-45-lib.il new file mode 100644 index 00000000000..c98948fb6d6 --- /dev/null +++ b/mcs/tests/gtest-exmethod-45-lib.il @@ -0,0 +1,30 @@ +.assembly extern mscorlib +{ +} + +.assembly 'gtest-exmethod-45-lib' +{ + .hash algorithm 0x00008004 +} + +.module 'gtest-exmethod-45-lib.dll' + +.class public abstract auto F +{ + .custom instance void class [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::'.ctor'() = (01 00 00 00 ) + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } + + .method public hidebysig static void TestExt(string s) cil managed + { + .custom instance void class [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::'.ctor'() = (01 00 00 00 ) + + ret + } +} diff --git a/mcs/tests/gtest-exmethod-45.cs b/mcs/tests/gtest-exmethod-45.cs new file mode 100644 index 00000000000..d11ab64f8e0 --- /dev/null +++ b/mcs/tests/gtest-exmethod-45.cs @@ -0,0 +1,10 @@ +// Compiler options: -r:gtest-exmethod-45-lib.dll + +public class C +{ + public static void Main () + { + string s = null; + s.TestExt (); + } +} \ No newline at end of file diff --git a/mcs/tests/property-il.il b/mcs/tests/property-il.il deleted file mode 100644 index 7115547feb6..00000000000 --- a/mcs/tests/property-il.il +++ /dev/null @@ -1,112 +0,0 @@ -.assembly extern mscorlib -{ - .ver 1:0:5000:0 -} -.assembly 'property-il' -{ - .hash algorithm 0x00008004 - .ver 0:0:0:0 -} -.module 'property-il.dll' // GUID = {CACC88BA-6ED4-45E0-8E59-C3ABEBA9753A} - - - .class public auto ansi beforefieldinit 'Foo' - extends [mscorlib]System.Object - { - - // method line 1 - .method public hidebysig specialname rtspecialname - instance default void .ctor () cil managed - { - // Method begins at RVA 0x20ec - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void valuetype [mscorlib]'System.Object'::.ctor() - IL_0006: ret - } // end of method Foo::instance default void .ctor () - - // method line 2 - .method public virtual hidebysig newslot specialname - instance default string 'Monkey_Jump' () cil managed - { - // Method begins at RVA 0x20f4 - // Code size 6 (0x6) - .maxstack 8 - IL_0000: ldstr "foo" - IL_0005: ret - } // end of method Foo::instance default string 'Monkey_Jump' () - - .property specialname rtspecialname string Message () - { - .get instance default string 'Foo'::'Monkey_Jump' () - } - } // end of type Foo - - .class public auto ansi beforefieldinit 'Bar' - extends Foo - { - - // method line 3 - .method public hidebysig specialname rtspecialname - instance default void .ctor () cil managed - { - // Method begins at RVA 0x20fb - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void class 'Foo'::.ctor() - IL_0006: ret - } // end of method Bar::instance default void .ctor () - - // method line 4 - .method public virtual hidebysig specialname - instance default string 'Boston' () cil managed - { - // Method begins at RVA 0x2103 - // Code size 6 (0x6) - .maxstack 8 - IL_0000: ldstr "bar" - IL_0005: ret - } // end of method Bar::instance default string 'Boston' () - - .property specialname rtspecialname string Message () - { - .get instance default string 'Bar'::'Boston' () - } - } // end of type Bar - -.class public auto ansi beforefieldinit C - extends [mscorlib]System.Object -{ - .method public hidebysig specialname instance int32 - get_Value() cil managed - { - .maxstack 1 - .locals init (int32 V_0) - IL_0000: ldc.i4.3 - IL_0001: stloc.0 - IL_0002: br.s IL_0004 - - IL_0004: ldloc.0 - IL_0005: ret - } - - .method public hidebysig specialname instance void - add_Arg(bool arg) cil managed - { - .maxstack 0 - IL_0000: ret - } - - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - .maxstack 1 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Object::.ctor() - IL_0006: ret - } - -} - diff --git a/mcs/tests/property-main.cs b/mcs/tests/property-main.cs deleted file mode 100644 index a6cd8a0bdfa..00000000000 --- a/mcs/tests/property-main.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -class X -{ - static int Main () - { - Bar bar = new Bar (); - if (bar.Message != "bar") - return 1; - - Foo foo = new Foo (); - if (foo.Message != "foo") - return 2; - - C c = new C (); - c.get_Value (); - c.add_Arg (false); - - Console.WriteLine ("Test ok"); - return 0; - } -} diff --git a/mcs/tests/test-792-lib.il b/mcs/tests/test-792-lib.il index 209b938b1df..175c506ad68 100644 --- a/mcs/tests/test-792-lib.il +++ b/mcs/tests/test-792-lib.il @@ -146,6 +146,12 @@ ret } + .method public hidebysig static void Test(object o, class ['missing-lib']XX o2, [opt] object o3) cil managed + { + .param [2] = nullref + ret + } + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/mcs/tests/test-849.cs b/mcs/tests/test-849.cs index 58be5f68f41..83310f20dcd 100644 --- a/mcs/tests/test-849.cs +++ b/mcs/tests/test-849.cs @@ -2,6 +2,11 @@ using System; class ConditionalPromotions { + public static int Test (bool condition, short value) + { + return condition ? -1 : value; + } + public static int Main(string[] args) { var r1 = args.Length > 0 ? 1 : (short)1; diff --git a/mcs/tests/test-855.cs b/mcs/tests/test-855.cs new file mode 100644 index 00000000000..29aa90ded60 --- /dev/null +++ b/mcs/tests/test-855.cs @@ -0,0 +1,29 @@ +namespace Test +{ + public interface IInterface + { + string Get (string key, string v); + int Get (string key, int v); + } + + public class BaseClass + { + public string Get (string key, string v) + { + return v; + } + + public int Get (string key, int v) + { + return 0; + } + } + + public class Subclass : BaseClass, IInterface + { + public static void Main () + { + new Subclass (); + } + } +} \ No newline at end of file diff --git a/mcs/tests/test-856.cs b/mcs/tests/test-856.cs new file mode 100644 index 00000000000..232a26a4bb5 --- /dev/null +++ b/mcs/tests/test-856.cs @@ -0,0 +1,38 @@ +using System; + +public abstract class A : IDisposable +{ + public int i; + + public virtual void Dispose () + { + ++i; + } +} + +public abstract class B : A +{ + private new void Dispose () + { + throw new ApplicationException ("B"); + } +} + +public class C : B +{ + public static int Main () + { + var c = new C (); + c.Dispose (); + if (c.i != 1) + return 1; + + return 0; + } + + public override void Dispose () + { + base.Dispose (); + } +} + diff --git a/mcs/tests/test-857.cs b/mcs/tests/test-857.cs new file mode 100644 index 00000000000..3da34d63a7a --- /dev/null +++ b/mcs/tests/test-857.cs @@ -0,0 +1,29 @@ +using System; + +public class Outer +{ + public enum Inner + { + ONE, + TWO + } +} + +public class TypeHiding +{ + + public static bool Test1 (Outer Outer) + { + return 0 == Outer.Inner.ONE; + } + + public static bool Test2 () + { + Outer Outer = null; + return 0 == Outer.Inner.ONE; + } + + public static void Main () + { + } +} \ No newline at end of file diff --git a/mcs/tests/test-858-lib.il b/mcs/tests/test-858-lib.il new file mode 100644 index 00000000000..20cd244c4b0 --- /dev/null +++ b/mcs/tests/test-858-lib.il @@ -0,0 +1,93 @@ +.assembly extern mscorlib +{ +} + +.assembly 'test-858-lib' +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} + +.module 'test-858-lib.dll' + +.class public auto ansi beforefieldinit 'Foo' + extends [mscorlib]System.Object + { + + .method public hidebysig specialname rtspecialname + instance default void .ctor () cil managed + { + ldarg.0 + call instance void valuetype [mscorlib]'System.Object'::.ctor() + ret + } + + .method public virtual hidebysig newslot specialname + instance default string 'Monkey_Jump' () cil managed + { + ldstr "foo" + ret + } + + .property specialname rtspecialname string Message () + { + .get instance default string 'Foo'::'Monkey_Jump' () + } +} + +.class public auto ansi beforefieldinit 'Bar' + extends Foo + { + .method public hidebysig specialname rtspecialname + instance default void .ctor () cil managed + { + ldarg.0 + call instance void class 'Foo'::.ctor() + ret + } + + .method public virtual hidebysig specialname + instance default string 'Boston' () cil managed + { + ldstr "bar" + ret + } + + .property specialname rtspecialname string Message () + { + .get instance default string 'Bar'::'Boston' () + } +} + +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .method public hidebysig specialname instance int32 + get_Value() cil managed + { + .locals init (int32 V_0) + IL_0000: ldc.i4.3 + IL_0001: stloc.0 + IL_0002: br.s IL_0004 + + IL_0004: ldloc.0 + IL_0005: ret + } + + .method public hidebysig specialname instance void + add_Arg(bool arg) cil managed + { + ret + } + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } +} + + + diff --git a/mcs/tests/test-858.cs b/mcs/tests/test-858.cs new file mode 100644 index 00000000000..778ea68bebb --- /dev/null +++ b/mcs/tests/test-858.cs @@ -0,0 +1,24 @@ +// Compiler options: -r:test-858-lib.dll + +using System; + +class X +{ + static int Main () + { + Bar bar = new Bar (); + if (bar.Message != "bar") + return 1; + + Foo foo = new Foo (); + if (foo.Message != "foo") + return 2; + + C c = new C (); + c.get_Value (); + c.add_Arg (false); + + Console.WriteLine ("Test ok"); + return 0; + } +} diff --git a/mcs/tests/test-859-lib.il b/mcs/tests/test-859-lib.il new file mode 100644 index 00000000000..94922baba06 --- /dev/null +++ b/mcs/tests/test-859-lib.il @@ -0,0 +1,39 @@ +.assembly extern mscorlib +{ +} + +.assembly 'test-859-lib' +{ + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} + +.module 'test-859-lib.dll' + +// Import flag enables more magic + +.class interface public auto ansi import C +{ + .method public hidebysig newslot specialname virtual abstract + instance object + get_Value([opt] object a) runtime managed preservesig internalcall + { + } + + .property object Value(object) + { + .get instance object C::get_Value(object) + } + + .method public hidebysig newslot specialname virtual abstract + instance void + set_Value2([opt] object a, [opt] object b) runtime managed preservesig internalcall + { + } + + .property object Value2(object) + { + .set instance void C::set_Value2(object, object) + } + +} diff --git a/mcs/tests/test-859.cs b/mcs/tests/test-859.cs new file mode 100644 index 00000000000..1737b9c7b18 --- /dev/null +++ b/mcs/tests/test-859.cs @@ -0,0 +1,24 @@ +// Compiler options: -r:test-859-lib.dll + +using System; + +class X +{ + void Test_PropertyOptionalParameters (C c) + { + // need to just run verifier on the method + if (c == null) + return; + + Console.WriteLine (c.Value); + c.Value2 = 1; + } + + static int Main () + { + var x = new X (); + x.Test_PropertyOptionalParameters (null); + + return 0; + } +} diff --git a/mcs/tests/test-async-41.cs b/mcs/tests/test-async-41.cs new file mode 100644 index 00000000000..0e8c0fa1e95 --- /dev/null +++ b/mcs/tests/test-async-41.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +public class AmbiguousGeneric +{ + public async void NestedVoidTestSuccess () + { + await Run2 (async () => await ReturnOne ()); + } + + static Task ReturnOne () + { + return Task.Run (() => 1); + } + + Task Run2 (Func arg) + { + return null; + } + + Task Run2 (Func arg) + { + return null; + } + + public static void Main () + { + } +} \ No newline at end of file diff --git a/mcs/tests/test-externalias-09.cs b/mcs/tests/test-externalias-09.cs index 10077a05d95..1c2bf37537a 100644 --- a/mcs/tests/test-externalias-09.cs +++ b/mcs/tests/test-externalias-09.cs @@ -1,9 +1,9 @@ -// Compiler options: -r:MyAssembly01=test-externalias-00-lib.dll +// Compiler options: -r:MyAssembly_01=test-externalias-00-lib.dll -extern alias MyAssembly01; +extern alias MyAssembly_01; using System; -using SameNamespace = MyAssembly01; +using SameNamespace = MyAssembly_01; public class Test { diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index 584b0f0e1e4..90d6a47eef9 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -14076,6 +14076,9 @@ 10 + + 53 + @@ -17656,6 +17659,35 @@ + + + + 0 + + + 7 + + + + + 20 + + + 15 + + + + + 20 + + + 10 + + + 7 + + + @@ -21157,6 +21189,16 @@ + + + + 10 + + + 7 + + + @@ -46015,6 +46057,9 @@ 7 + + 22 + @@ -46083,6 +46128,100 @@ + + + + 10 + + + 10 + + + 7 + + + + + 8 + + + 7 + + + + + + + 16 + + + 7 + + + + + 12 + + + 7 + + + + + 41 + + + 8 + + + 7 + + + + + + + 7 + + + + + 10 + + + 12 + + + 2 + + + 7 + + + + + + + 108 + + + 7 + + + + + + + 46 + + + 23 + + + 7 + + + @@ -56964,6 +57103,50 @@ + + + + 35 + + + 43 + + + 10 + + + 10 + + + 2 + + + 9 + + + 7 + + + + + 191 + + + 13 + + + 33 + + + + + 162 + + + 13 + + + diff --git a/mcs/tools/csharp/getline.cs b/mcs/tools/csharp/getline.cs index e8b9783e614..b6dcf0759b6 100644 --- a/mcs/tools/csharp/getline.cs +++ b/mcs/tools/csharp/getline.cs @@ -869,6 +869,13 @@ namespace Mono.Terminal { return result; } + + public void SaveHistory () + { + if (history != null) { + history.Close (); + } + } public bool TabAtStartCompletes { get; set; } diff --git a/mcs/tools/csharp/repl.cs b/mcs/tools/csharp/repl.cs index 24a5d2a5ef5..89af0a942b7 100644 --- a/mcs/tools/csharp/repl.cs +++ b/mcs/tools/csharp/repl.cs @@ -314,7 +314,7 @@ namespace Mono { expr = expr == null ? input : expr + "\n" + input; expr = Evaluate (expr); - } + } } public int ReadEvalPrintLoop () @@ -326,17 +326,24 @@ namespace Mono { LoadStartupFiles (); - if (startup_files != null && startup_files.Length != 0) + if (startup_files != null && startup_files.Length != 0) { ExecuteSources (startup_files, false); - else if (Driver.StartupEvalExpression != null){ - ReadEvalPrintLoopWith (p => { - var ret = Driver.StartupEvalExpression; - Driver.StartupEvalExpression = null; - return ret; - }); - } else - ReadEvalPrintLoopWith (GetLine); + } else { + if (Driver.StartupEvalExpression != null){ + ReadEvalPrintLoopWith (p => { + var ret = Driver.StartupEvalExpression; + Driver.StartupEvalExpression = null; + return ret; + }); + } else { + ReadEvalPrintLoopWith (GetLine); + } + + editor.SaveHistory (); + } + Console.CancelKeyPress -= ConsoleInterrupt; + return 0; } diff --git a/mcs/tools/linker/Mono.Linker/LinkContext.cs b/mcs/tools/linker/Mono.Linker/LinkContext.cs index 4f84e43eba5..8d97f8dc150 100644 --- a/mcs/tools/linker/Mono.Linker/LinkContext.cs +++ b/mcs/tools/linker/Mono.Linker/LinkContext.cs @@ -144,15 +144,19 @@ namespace Mono.Linker { public AssemblyDefinition Resolve (IMetadataScope scope) { AssemblyNameReference reference = GetReference (scope); + try { + AssemblyDefinition assembly = _resolver.Resolve (reference, _readerParameters); - AssemblyDefinition assembly = _resolver.Resolve (reference, _readerParameters); + if (SeenFirstTime (assembly)) { + SafeReadSymbols (assembly); + SetAction (assembly); + } - if (SeenFirstTime (assembly)) { - SafeReadSymbols (assembly); - SetAction (assembly); + return assembly; + } + catch { + throw new AssemblyResolutionException (reference); } - - return assembly; } bool SeenFirstTime (AssemblyDefinition assembly) diff --git a/mcs/tools/mdoc/Mono.Documentation/ecmadoc.cs b/mcs/tools/mdoc/Mono.Documentation/ecmadoc.cs index e8c0a5cd5bd..86f8a7c6315 100644 --- a/mcs/tools/mdoc/Mono.Documentation/ecmadoc.cs +++ b/mcs/tools/mdoc/Mono.Documentation/ecmadoc.cs @@ -115,7 +115,7 @@ namespace Mono.Documentation return CreateDefaultDocument (); var settings = new XmlReaderSettings { - ProhibitDtd = false, + DtdProcessing = DtdProcessing.Parse }; using (var reader = XmlReader.Create (file, settings)) return XDocument.Load (reader); diff --git a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs index a930951268c..dcb23d2f17c 100644 --- a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs +++ b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs @@ -60,6 +60,8 @@ class MDocUpdater : MDocCommand MyXmlNodeList extensionMethods = new MyXmlNodeList (); + HashSet forwardedTypes = new HashSet (); + public override void Run (IEnumerable args) { show_exceptions = DebugOutput; @@ -142,6 +144,9 @@ class MDocUpdater : MDocCommand this.assemblies = assemblies.Select (a => LoadAssembly (a)).ToList (); + // Store types that have been forwarded to avoid duplicate generation + GatherForwardedTypes (); + docEnum = docEnum ?? new DocumentationEnumerator (); // PERFORM THE UPDATES @@ -188,6 +193,13 @@ class MDocUpdater : MDocCommand } } + void GatherForwardedTypes () + { + foreach (var asm in assemblies) + foreach (var type in asm.MainModule.ExportedTypes.Where (t => t.IsForwarder).Select (t => t.FullName)) + forwardedTypes.Add (type); + } + static ExceptionLocations ParseExceptionLocations (string s) { ExceptionLocations loc = ExceptionLocations.Member; @@ -641,7 +653,7 @@ class MDocUpdater : MDocCommand { foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, null)) { string typename = GetTypeFileName(type); - if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0) + if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0 || forwardedTypes.Contains (type.FullName)) continue; string reltypepath = DoUpdateType (type, source, dest); diff --git a/mcs/tools/monkeydoc/Assembly/AssemblyInfo.cs b/mcs/tools/monkeydoc/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..61c5fdcb700 --- /dev/null +++ b/mcs/tools/monkeydoc/Assembly/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly:AssemblyVersion("1.0.0.0")] +[assembly:AssemblyDelaySign(false)] +[assembly:AssemblyKeyFile("../../class/mono.snk")] diff --git a/mcs/tools/monkeydoc/Makefile b/mcs/tools/monkeydoc/Makefile new file mode 100644 index 00000000000..890d06d7ef6 --- /dev/null +++ b/mcs/tools/monkeydoc/Makefile @@ -0,0 +1,141 @@ +thisdir = tools/monkeydoc +SUBDIRS = +include ../../build/rules.make + +LIBRARY = monkeydoc.dll +LIBRARY_PACKAGE = monkeydoc +# Remove a bunch of "obsolete"-type warning for Lucene.NET +LOCAL_MCS_FLAGS = /nowarn:618,612,672,809 + +JAY_FLAGS = -ct + +IMAGES = \ + Resources/images/bc_bg.png \ + Resources/images/bc_separator.png \ + Resources/images/error.png \ + Resources/images/hatch.png \ + Resources/images/headerbg.png \ + Resources/images/help.png \ + Resources/images/house.png \ + Resources/images/members.png \ + Resources/images/namespace.png \ + Resources/images/privclass.png \ + Resources/images/privdelegate.png \ + Resources/images/privenumeration.png \ + Resources/images/privevent.png \ + Resources/images/privextension.png \ + Resources/images/privfield.png \ + Resources/images/privinterface.png \ + Resources/images/privmethod.png \ + Resources/images/privproperty.png \ + Resources/images/privstructure.png \ + Resources/images/protclass.png \ + Resources/images/protdelegate.png \ + Resources/images/protenumeration.png \ + Resources/images/protevent.png \ + Resources/images/protextension.png \ + Resources/images/protfield.png \ + Resources/images/protinterface.png \ + Resources/images/protmethod.png \ + Resources/images/protproperty.png \ + Resources/images/protstructure.png \ + Resources/images/pubclass.png \ + Resources/images/pubdelegate.png \ + Resources/images/pubenumeration.png \ + Resources/images/pubevent.png \ + Resources/images/pubextension.png \ + Resources/images/pubfield.png \ + Resources/images/pubinterface.png \ + Resources/images/pubmethod.png \ + Resources/images/pubproperty.png \ + Resources/images/pubstructure.png \ + Resources/images/reference.png \ + Resources/images/treebg.png + +IMAGE_RESOURCE_COMMAND = $(foreach file,$(IMAGES),/resource:$(file),$(notdir $(file))) + +RESOURCE_FILES = \ + ../../docs/monodoc.xml \ + Resources/base.css \ + Resources/ecmaspec-html-css.xsl \ + Resources/ecmaspec-html.xsl \ + Resources/ecmaspec.css \ + Resources/helper.js \ + Resources/home.html \ + Resources/Lminus.gif \ + Resources/Lplus.gif \ + Resources/mdoc-html-format.xsl \ + Resources/mdoc-html-utils.xsl \ + Resources/mdoc-sections-css.xsl \ + Resources/mdoc-sections.xsl \ + Resources/mono-ecma-css.xsl \ + Resources/mono-ecma-impl.xsl \ + Resources/mono-ecma.css \ + Resources/mono-ecma.xsl \ + Resources/toc-html.xsl \ + $(IMAGES) + +EXTRA_DISTFILES = \ + monkeydoc.dll.config.in \ + $(RESOURCE_FILES) + +LIB_MCS_FLAGS = \ + /unsafe \ + /codepage:utf8 \ + /nowarn:169,164,162,168,219,618,612 \ + /r:Commons.Xml.Relaxng \ + /resource:../../docs/monodoc.xml,monodoc.xml \ + /resource:Resources/base.css,base.css \ + /resource:Resources/ecmaspec-html-css.xsl,ecmaspec-html-css.xsl \ + /resource:Resources/ecmaspec-html.xsl,ecmaspec-html.xsl \ + /resource:Resources/ecmaspec.css,ecmaspec.css \ + /resource:Resources/helper.js,helper.js \ + /resource:Resources/home.html,home.html \ + /resource:Resources/Lminus.gif,Lminus.gif \ + /resource:Resources/Lplus.gif,Lplus.gif \ + /resource:Resources/mdoc-html-format.xsl,mdoc-html-format.xsl \ + /resource:Resources/mdoc-html-utils.xsl,mdoc-html-utils.xsl \ + /resource:Resources/mdoc-sections-css.xsl,mdoc-sections-css.xsl \ + /resource:Resources/mdoc-sections.xsl,mdoc-sections.xsl \ + /resource:Resources/mono-ecma-css.xsl,mono-ecma-css.xsl \ + /resource:Resources/mono-ecma-impl.xsl,mono-ecma-impl.xsl \ + /resource:Resources/mono-ecma.css,mono-ecma.css \ + /resource:Resources/mono-ecma.xsl,mono-ecma.xsl \ + /resource:Resources/toc-html.xsl,toc-html.xsl \ + $(IMAGE_RESOURCE_COMMAND) \ + /r:ICSharpCode.SharpZipLib \ + /r:$(corlib) \ + /r:System.dll \ + /r:System.Core.dll \ + /r:System.Xml.dll \ + /r:System.Xml.Linq.dll \ + /r:System.Configuration.dll + +TEST_MCS_FLAGS = /r:System.Core.dll + +DOC_SOURCE_DIRS = \ + ../../docs \ + ../../../docs + +DOC_SOURCES = $(foreach dir,$(DOC_SOURCE_DIRS),$(wildcard $(dir)/*.source $(dir)/*.tree $(dir)/*.zip)) + +include ../../build/library.make + +$(the_lib): Makefile $(RESOURCE_FILES) + +all-local: $(the_lib).config Monkeydoc.Ecma/EcmaUrlParser.cs + +test-local: setup-doc-sources + +$(the_lib).config: Makefile + sed 's,@monodoc_refdir@,$(mono_libdir)/monodoc,g' monkeydoc.dll.config.in > $@ + +Monkeydoc.Ecma/EcmaUrlParser.cs: Monkeydoc.Ecma/EcmaUrlParser.jay $(topdir)/jay/skeleton.cs + $(topdir)/jay/jay $(JAY_FLAGS) < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@ + +parser.exe: Monkeydoc.Ecma/EcmaUrlParser.cs Monkeydoc.Ecma/EcmaUrlTokenizer.cs Monkeydoc.Ecma/EcmaUrlParserDriver.cs Monkeydoc.Ecma/EcmaDesc.cs + mcs /out:$@ /debug $^ + +setup-doc-sources: $(DOC_SOURCES) + mkdir -p ./Test/monodoc/sources/ + cp $(DOC_SOURCES) ./Test/monodoc/sources/ diff --git a/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaDesc.cs b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaDesc.cs new file mode 100644 index 00000000000..e8fa191b1ab --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaDesc.cs @@ -0,0 +1,333 @@ +using System; +using System.Linq; +using System.Text; +using System.Collections.Generic; + +namespace Monkeydoc.Ecma +{ + /* Some properties might not be filled/meaningful depending on kind + * like a namespace EcmaUrl won't have a valid TypeName + */ + public class EcmaDesc : IEquatable + { + public enum Kind + { + Type, + Constructor, + Method, + Namespace, + Field, + Property, + Event, + Operator + } + + public enum Mod + { + Normal, + Pointer, + Ref, + Out + } + + public enum Format + { + WithArgs, + WithoutArgs + } + + public Kind DescKind { + get; + set; + } + + public Mod DescModifier { + get; + set; + } + + public string Namespace { + get; + set; + } + + public string TypeName { + get; + set; + } + + public string MemberName { + get; + set; + } + + public EcmaDesc NestedType { + get; + set; + } + + /* A list of the array dimensions attached to this type. + * The list count corresponds to the number of recursive + * array definition (jagged arrays) the value of the + * corresponding list item is the number of dimension + * attached to that array definition instance + */ + public IList ArrayDimensions { + get; + set; + } + + /* Depending on the form of the url, we might not have the type + * of the argument but only how many the type/member has i.e. + * when such number is specified with a backtick + */ + public IList GenericTypeArguments { + get; + set; + } + + public IList GenericMemberArguments { + get; + set; + } + + public IList MemberArguments { + get; + set; + } + + /* This indicates that we actually want an inner part of the ecmadesc + * i.e. in case of T: we could want the members (*), ctor (C), methods (M), ... + */ + public char Etc { + get; + set; + } + + public bool IsEtc { + get { + return Etc != (char)0; + } + } + + /* EtcFilter is only valid in some case of IsEtc when the inner part needs + * to be further filtered e.g. in case we want a listing of the type overloads + * Equals + */ + public string EtcFilter { + get; + set; + } + + /* When a member is an explicit implementation of an interface member, we register + * the member EcmaDesc with its interface parent here + */ + public EcmaDesc ExplicitImplMember { + get; + set; + } + + // Returns the TypeName and the generic/inner type information if existing + public string ToCompleteTypeName (char innerTypeSeparator = '.') + { + var result = TypeName; + if (GenericTypeArguments != null) + result += FormatGenericArgs (GenericTypeArguments); + if (NestedType != null) + result += innerTypeSeparator + NestedType.ToCompleteTypeName (); + if (ArrayDimensions != null && ArrayDimensions.Count > 0) + result += ArrayDimensions.Select (dim => "[" + new string (',', dim - 1) + "]").Aggregate (string.Concat); + + return result; + } + + // Returns the member name with its generic types if existing + public string ToCompleteMemberName (Format format) + { + /* We special process two cases: + * - Explicit member implementation which append a full type specification + * - Conversion operator which are exposed as normal method but have specific captioning in the end + */ + if (ExplicitImplMember != null) { + var impl = ExplicitImplMember; + return impl.FormattedNamespace + impl.ToCompleteTypeName () + "." + impl.ToCompleteMemberName (format); + } else if (format == Format.WithArgs && DescKind == Kind.Operator && MemberName.EndsWith ("Conversion")) { + var type1 = MemberArguments[0].FormattedNamespace + MemberArguments[0].ToCompleteTypeName () + ModToString (MemberArguments[0]); + var type2 = MemberArguments[1].FormattedNamespace + MemberArguments[1].ToCompleteTypeName () + ModToString (MemberArguments[1]); + return type1 + " to " + type2; + } + + var result = IsEtc && !string.IsNullOrEmpty (EtcFilter) ? EtcFilter : MemberName; + + // Temporary hack for monodoc produced inner type ctor + //if (DescKind == Kind.Constructor && NestedType != null) + //result = ToCompleteTypeName (); + + if (GenericMemberArguments != null) + result += FormatGenericArgs (GenericMemberArguments); + + if (format == Format.WithArgs) { + result += '('; + if (MemberArguments != null && MemberArguments.Count > 0) { + var args = MemberArguments.Select (a => FormatNamespace (a) + a.ToCompleteTypeName ('+') + ModToString (a)); + result += string.Join (",", args); + } + result += ')'; + } + + return result; + } + + public string ToEcmaCref () + { + var sb = new StringBuilder (); + // Cref type + sb.Append (DescKind.ToString ()[0]); + // Create the rest + ConstructCRef (sb); + + return sb.ToString (); + } + + void ConstructCRef (StringBuilder sb) + { + sb.Append (Namespace); + if (DescKind == Kind.Namespace) + return; + + sb.Append ('.'); + sb.Append (TypeName); + if (GenericTypeArguments != null) { + sb.Append ('<'); + foreach (var t in GenericTypeArguments) + t.ConstructCRef (sb); + sb.Append ('>'); + } + if (NestedType != null) { + sb.Append ('+'); + NestedType.ConstructCRef (sb); + } + if (ArrayDimensions != null && ArrayDimensions.Count > 0) { + for (int i = 0; i < ArrayDimensions.Count; i++) { + sb.Append ('['); + sb.Append (new string (',', ArrayDimensions[i] - 1)); + sb.Append (']'); + } + } + if (DescKind == Kind.Type) + return; + + if (MemberArguments != null) { + + } + } + + public override string ToString () + { + return string.Format ("({8}) {0}::{1}{2}{3}{7} {4}{5}{6} {9} {10}", + Namespace, + TypeName, + FormatGenericArgsFull (GenericTypeArguments), + NestedType != null ? "+" + NestedType.ToString () : string.Empty, + MemberName ?? string.Empty, + FormatGenericArgsFull (GenericMemberArguments), + MemberArguments != null ? "(" + string.Join (",", MemberArguments.Select (m => m.ToString ())) + ")" : string.Empty, + ArrayDimensions != null && ArrayDimensions.Count > 0 ? ArrayDimensions.Select (dim => "[" + new string (',', dim - 1) + "]").Aggregate (string.Concat) : string.Empty, + DescKind.ToString ()[0], + Etc != 0 ? '(' + Etc.ToString () + ')' : string.Empty, + ExplicitImplMember != null ? "$" + ExplicitImplMember.ToString () : string.Empty); + + } + + public override bool Equals (object other) + { + var otherDesc = other as EcmaDesc; + return otherDesc != null && Equals (otherDesc); + } + + public bool Equals (EcmaDesc other) + { + if (other == null) + return false; + + if (NestedType == null ^ other.NestedType == null + || ArrayDimensions == null ^ other.ArrayDimensions == null + || GenericTypeArguments == null ^ other.GenericTypeArguments == null + || GenericMemberArguments == null ^ other.GenericMemberArguments == null + || MemberArguments == null ^ other.MemberArguments == null + || ExplicitImplMember == null ^ other.ExplicitImplMember == null) + return false; + + return other != null + && DescKind == other.DescKind + && TypeName == other.TypeName + && Namespace == other.Namespace + && MemberName == other.MemberName + && (NestedType == null || NestedType.Equals (other.NestedType)) + && (ArrayDimensions == null || ArrayDimensions.SequenceEqual (other.ArrayDimensions)) + && (GenericTypeArguments == null || GenericTypeArguments.SequenceEqual (other.GenericTypeArguments)) + && (GenericMemberArguments == null || GenericMemberArguments.SequenceEqual (other.GenericMemberArguments)) + && (MemberArguments == null || MemberArguments.SequenceEqual (other.MemberArguments)) + && Etc == other.Etc + && EtcFilter == other.EtcFilter + && (ExplicitImplMember == null || ExplicitImplMember.Equals (other.ExplicitImplMember)); + } + + public override int GetHashCode () + { + return DescKind.GetHashCode () + ^ TypeName.GetHashCode () + ^ Namespace.GetHashCode () + ^ MemberName.GetHashCode (); + } + + bool What (bool input) + { + if (!input) + throw new Exception ("Not equal"); + return input; + } + + bool WhatT (bool input) + { + if (input) + throw new Exception ("Not equal"); + return input; + } + + string FormatNamespace (EcmaDesc desc) + { + return string.IsNullOrEmpty (desc.Namespace) ? string.Empty : desc.Namespace + "."; + } + + string FormatGenericArgs (IEnumerable genericArgs) + { + return genericArgs != null ? "<" + string.Join (",", genericArgs.Select (t => FormatNamespace (t) + t.ToCompleteTypeName ())) + ">" : string.Empty; + } + + string FormatGenericArgsFull (IEnumerable genericArgs) + { + return genericArgs != null ? "<" + string.Join (",", genericArgs.Select (t => t.ToString ())) + ">" : string.Empty; + } + + string ModToString (EcmaDesc desc) + { + switch (desc.DescModifier) { + case Mod.Pointer: + return "*"; + case Mod.Ref: + return "&"; + case Mod.Out: + return "@"; + default: + return string.Empty; + } + } + + string FormattedNamespace { + get { + return !string.IsNullOrEmpty (Namespace) ? Namespace + "." : string.Empty; + } + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParser.jay b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParser.jay new file mode 100644 index 00000000000..bee281049a6 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParser.jay @@ -0,0 +1,263 @@ +%{ +using System.Text; +using System.IO; +using System; +using System.Linq; +using System.Collections.Generic; + +namespace Monkeydoc.Ecma +{ + public class EcmaUrlParser + { + int yacc_verbose_flag = 0; + + public void IsValid (string input) + { + var lexer = new EcmaUrlTokenizer (input); + this.yyparse (lexer); + } + + public EcmaDesc Parse (string input) + { + var lexer = new EcmaUrlTokenizer (input); + return (EcmaDesc)this.yyparse (lexer); + } + + public bool TryParse (string input, out EcmaDesc desc) + { + desc = null; + try { + desc = Parse (input); + } catch { + return false; + } + return true; + } + + EcmaDesc SetEcmaDescType (object result, EcmaDesc.Kind kind) + { + var desc = result as EcmaDesc; + desc.DescKind = kind; + return desc; + } + + List SafeReverse (List input) + { + if (input == null) + return null; + input.Reverse (); + return input; + } +%} + +%token ERROR +%token IDENTIFIER +%token DIGIT +%token DOT +%token COMMA +%token COLON +%token INNER_TYPE_SEPARATOR +%token OP_GENERICS_LT +%token OP_GENERICS_GT +%token OP_GENERICS_BACKTICK +%token OP_OPEN_PAREN +%token OP_CLOSE_PAREN +%token OP_ARRAY_OPEN +%token OP_ARRAY_CLOSE +%token SLASH_SEPARATOR +%token STAR +%token REF_ARG +%token OUT_ARG +%token EXPLICIT_IMPL_SEP + +%start expression + +%% + +expression + : 'T' COLON type_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Type); } + | 'N' COLON namespace_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Namespace); } + | 'M' COLON method_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Method); } + | 'F' COLON simple_member_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Field); } + | 'C' COLON constructor_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Constructor); } + | 'P' COLON property_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Property); } + | 'E' COLON simple_member_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Event); } + | 'O' COLON operator_expression { $$ = SetEcmaDescType ($3, EcmaDesc.Kind.Operator); } + +/* i.e. id.id.id or id */ +dot_expression + : IDENTIFIER { $$ = new List { (string)$1 }; } + | IDENTIFIER DOT dot_expression { ((ICollection)$3).Add ((string)$1); $$ = $3; } + +namespace_expression + : dot_expression { $$ = new EcmaDesc { Namespace = string.Join (".", ((IEnumerable)$1).Reverse ()) }; } + +type_expression + : dot_expression type_expression_suffix { + var dotExpr = ((List)$1); + dotExpr.Reverse (); + var desc = $2 as EcmaDesc; + desc.DescKind = EcmaDesc.Kind.Type; + desc.Namespace = string.Join (".", dotExpr.Take (dotExpr.Count - 1)); + desc.TypeName = dotExpr.Last (); + $$ = desc; + } + +/* To be used in types with no namespaces attached to them like an inner type*/ +reduced_type_expression + : IDENTIFIER type_expression_suffix { + var desc = $2 as EcmaDesc; + desc.DescKind = EcmaDesc.Kind.Type; + desc.TypeName = $1 as string; + $$ = desc; + } + +type_expression_suffix + : opt_generic_type_suffix opt_inner_type_description opt_array_definition opt_etc { + bool nestedDescHasEtc = $2 != null && ((EcmaDesc)$2).IsEtc; + EcmaDesc nestedType = (EcmaDesc)$2; + $$ = new EcmaDesc { + GenericTypeArguments = $1 as List, + NestedType = nestedType, + ArrayDimensions = SafeReverse ($3 as List), + Etc = $4 != null ? ((Tuple)$4).Item1 : nestedDescHasEtc ? nestedType.Etc : (char)0, + EtcFilter = $4 != null ? ((Tuple)$4).Item2 : nestedDescHasEtc ? nestedType.EtcFilter : null + }; + if (nestedDescHasEtc) { + nestedType.Etc = (char)0; + nestedType.EtcFilter = null; + } + } + +opt_inner_type_description + : /* empty */ { $$ = null; } + | INNER_TYPE_SEPARATOR reduced_type_expression { $$ = $2; } + +opt_generic_type_suffix + : /* empty */ { $$ = null; } + | OP_GENERICS_BACKTICK DIGIT { $$ = Enumerable.Repeat (null, (int)$2).ToList (); } + | OP_GENERICS_LT generic_type_arg_list OP_GENERICS_GT { $$ = $2; } + +generic_type_arg_list + : type_expression { $$ = new List () { (EcmaDesc)$1 }; } + | generic_type_arg_list COMMA type_expression { ((List)$1).Add ((EcmaDesc)$3); $$ = $1; } + +opt_array_definition + : /* empty */ { $$ = null; } + | OP_ARRAY_OPEN opt_array_definition_list OP_ARRAY_CLOSE opt_array_definition { + var dims = ((IList)$4) ?? new List (2); + dims.Add ((int)$2); + $$ = dims; + } + +opt_array_definition_list + : /* empty */ { $$ = 1; } + | COMMA opt_array_definition_list { $$ = ((int)$2) + 1; } + +opt_etc + : /* empty */ { $$ = null; } + | SLASH_SEPARATOR etc_identifier { $$ = Tuple.Create (((string)$2)[0], null); } + | SLASH_SEPARATOR etc_identifier SLASH_SEPARATOR reduced_member_expression { $$ = Tuple.Create (((string)$2)[0], (string)$4); } +/* | SLASH_SEPARATOR etc_identifier SLASH_SEPARATOR IDENTIFIER opt_generic_type_suffix { $$ = Tuple.Create (((string)$2)[0], (string)$4 + ($5 == null ? string.Empty : "<" + string.Join (",", ((IEnumerable)$5).Select (t => t.ToCompleteTypeName ())) + ">")); } */ + +etc_identifier + : STAR { $$ = "*"; } + | IDENTIFIER { $$ = $1; } + +method_expression + : type_expression DOT IDENTIFIER opt_generic_type_suffix opt_arg_list_suffix { + var desc = $1 as EcmaDesc; + desc.MemberName = $3 as string; + desc.GenericMemberArguments = $4 as List; + desc.MemberArguments = SafeReverse ($5 as List); + $$ = desc; + } + | dot_expression opt_generic_type_suffix opt_arg_list_suffix { + var dotExpr = ((List)$1); + $$ = new EcmaDesc { + Namespace = string.Join (".", dotExpr.Skip (2).DefaultIfEmpty (string.Empty).Reverse ()), + TypeName = dotExpr.Skip (1).First (), + MemberName = dotExpr.First (), + GenericMemberArguments = $2 as List, + MemberArguments = SafeReverse ($3 as List) + }; + } + | type_expression EXPLICIT_IMPL_SEP method_expression { + var desc = $1 as EcmaDesc; + desc.ExplicitImplMember = $3 as EcmaDesc; + $$ = desc; + } + +/* To be used with members that may have no type/namespace attached */ +reduced_member_expression + : IDENTIFIER opt_generic_type_suffix { $$ = (string)$1 + ($2 == null ? string.Empty : "<" + string.Join (",", ((IEnumerable)$2).Select (t => t.ToCompleteTypeName ())) + ">"); } + | IDENTIFIER opt_generic_type_suffix DOT reduced_member_expression { + var existing = $4 as string; + var expr = (string)$1 + ($2 == null ? string.Empty : "<" + string.Join (",", ((IEnumerable)$2).Select (t => t.ToCompleteTypeName ())) + ">"); + $$ = expr + "." + existing; + } + +arg_type_expression + : type_expression opt_arg_type_suffix { var desc = (EcmaDesc)$1; desc.DescModifier = (EcmaDesc.Mod)$2; $$ = desc; } + +opt_arg_type_suffix + : /* empty */ { $$ = EcmaDesc.Mod.Normal; } + | STAR { $$ = EcmaDesc.Mod.Pointer; } + | REF_ARG { $$ = EcmaDesc.Mod.Ref; } + | OUT_ARG { $$ = EcmaDesc.Mod.Out; } + +type_expression_list + : /* empty */ { $$ = null; } + | arg_type_expression { $$ = new List () { (EcmaDesc)$1 }; } + | arg_type_expression COMMA type_expression_list { ((List)$3).Add ((EcmaDesc)$1); $$ = $3; } + +simple_member_expression + : dot_expression { + var dotExpr = ((List)$1); + dotExpr.Reverse (); + + $$ = new EcmaDesc { + Namespace = dotExpr.Count > 2 ? string.Join (".", dotExpr.Take (dotExpr.Count - 2)) : string.Empty, + TypeName = dotExpr.Count > 1 ? dotExpr[dotExpr.Count - 2] : string.Empty, + MemberName = dotExpr[dotExpr.Count - 1] + }; + } + | type_expression DOT IDENTIFIER { + var desc = $1 as EcmaDesc; + desc.MemberName = $3 as string; + $$ = desc; + } + | type_expression EXPLICIT_IMPL_SEP simple_member_expression { + var desc = $1 as EcmaDesc; + desc.ExplicitImplMember = $3 as EcmaDesc; + $$ = desc; + } + +constructor_expression + : method_expression { $$ = $1; } + +operator_expression + : method_expression { $$ = $1; } + +property_expression + : simple_member_expression opt_property_indexer { + var desc = $1 as EcmaDesc; + (desc.ExplicitImplMember ?? desc).MemberArguments = SafeReverse ($2 as List); + $$ = desc; + } + +opt_property_indexer + : opt_arg_list_suffix { $$ = $1; } + +/*simple_member_expression opt_arg_list_suffix { $$ = CopyFromEcmaDesc (new EcmaDesc { + MemberArguments = SafeReverse ($2 as List) + }, (EcmaDesc)$1); + }*/ + +opt_arg_list_suffix + : /* empty */ { $$ = null; } + | OP_OPEN_PAREN type_expression_list OP_CLOSE_PAREN { $$ = $2; } + +%% + +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParserDriver.cs b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParserDriver.cs new file mode 100644 index 00000000000..93e8c355aeb --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlParserDriver.cs @@ -0,0 +1,17 @@ +using System; +using System.IO; + +namespace Monkeydoc.Ecma +{ + public class EcmaUrlParserDriver + { + public static void Main (string[] args) + { + var input = new StringReader (args[0]); + var lexer = new EcmaUrlTokenizer (input); + var parser = new EcmaUrlParser (); + + Console.WriteLine (parser.yyparse (lexer)); + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlTokenizer.cs b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlTokenizer.cs new file mode 100644 index 00000000000..bb1ffb14229 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc.Ecma/EcmaUrlTokenizer.cs @@ -0,0 +1,168 @@ +using System; +using System.Text; +using System.Globalization; + +namespace Monkeydoc.Ecma +{ + public class EcmaUrlTokenizer : yyParser.yyInput + { + const char EndOfStream = (char)0; + string input; + object val; + int current_token; + int current_pos; + int real_current_pos; + int identCount = 0; + + public EcmaUrlTokenizer (string input) + { + this.input = input; + } + + static bool is_identifier_start_character (char c) + { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || Char.IsLetter (c); + } + + static bool is_identifier_part_character (char c) + { + if (c >= 'a' && c <= 'z') + return true; + + if (c >= 'A' && c <= 'Z') + return true; + + if (c == '_' || (c >= '0' && c <= '9')) + return true; + + if (c < 0x80) + return false; + + return Char.IsLetter (c) || Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation; + } + + public bool advance () + { + return Peek () != EndOfStream; + } + + public Object Value { + get { + return val; + } + } + + public Object value () + { + return val; + } + + public int token () + { + int token = xtoken (); + //Console.WriteLine ("Current token {0} with value {1}", token, val == null ? "(none)" : val.ToString ()); + if (token == Token.ERROR) + Console.WriteLine ("Problem at pos {0} after token {1}", current_pos, current_token); + current_token = token; + return token; + } + + int xtoken () + { + char next = Read (); + while (char.IsWhiteSpace (next)) + next = Read (); + current_pos++; + val = null; + + switch (next) { + case ',': + return Token.COMMA; + case '.': + return Token.DOT; + case '<': + return Token.OP_GENERICS_LT; + case '>': + return Token.OP_GENERICS_GT; + case '`': + return Token.OP_GENERICS_BACKTICK; + case '(': + return Token.OP_OPEN_PAREN; + case ')': + return Token.OP_CLOSE_PAREN; + case '+': + return Token.INNER_TYPE_SEPARATOR; + case ':': + return Token.COLON; + case '/': + return Token.SLASH_SEPARATOR; + case '[': + return Token.OP_ARRAY_OPEN; + case ']': + return Token.OP_ARRAY_CLOSE; + case '*': + return Token.STAR; + case '&': + return Token.REF_ARG; + case '@': + return Token.OUT_ARG; + case '$': + return Token.EXPLICIT_IMPL_SEP; + default: + return TokenizeIdentifierOrNumber (next); + } + } + + int TokenizeIdentifierOrNumber (char current) + { + // We must first return the expression type which is a uppercase letter and a colon + if (current_pos < 2) { + val = null; + return (int)current; + } + + if (is_identifier_start_character (current) || current == '*') { + unsafe { + // identifier length is artificially limited to 1024 bytes by implementations + char* pIdent = stackalloc char[512]; + *pIdent = current; + identCount = 1; + + char peek; + while ((peek = Peek ()) != EndOfStream && is_identifier_part_character (peek)) { + *(pIdent + identCount) = Read (); + ++current_pos; + ++identCount; + } + + val = new string ((char*)pIdent, 0, identCount); + return Token.IDENTIFIER; + } + } else if (char.IsDigit (current)) { + val = current - '0'; + return Token.DIGIT; + } else { + val = null; + return Token.ERROR; + } + } + + char Read () + { + try { + return input[real_current_pos++]; + } catch { + return EndOfStream; + } + } + + char Peek () + { + try { + return input[real_current_pos]; + } catch { + return EndOfStream; + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/HelpSource.cs b/mcs/tools/monkeydoc/Monkeydoc/HelpSource.cs new file mode 100644 index 00000000000..b22742b35e3 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/HelpSource.cs @@ -0,0 +1,335 @@ +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Diagnostics; +using System.Collections.Generic; + +using Mono.Utilities; +using Lucene.Net.Index; + +namespace MonkeyDoc +{ + // + // The HelpSource class keeps track of the archived data, and its + // tree + // + public class HelpSource + { + static int id; + + // + // The unique ID for this HelpSource. + // + int source_id; + + // The name of the HelpSource, used by all the file (.tree, .zip, ...) used by it + string name; + // The full directory path where the HelpSource files are located + string basePath; + + // The tree of this help source + Tree tree; + string treeFilePath; + RootTree rootTree; + + IDocCache cache = new MonkeyDoc.Caches.FileCache (Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "monkeydoc", "cache")); + IDocStorage storage; + + public HelpSource (string base_filename, bool create) + { + this.name = Path.GetFileName (base_filename); + this.basePath = Path.GetDirectoryName (base_filename); + this.treeFilePath = base_filename + ".tree"; + this.storage = new MonkeyDoc.Storage.ZipStorage (base_filename + ".zip"); + + tree = create ? new Tree (this, string.Empty, string.Empty) : new Tree (this, treeFilePath); + + source_id = id++; + } + + public HelpSource () + { + tree = new Tree (this, "Blah", "Blah"); + source_id = id++; + } + + public int SourceID { + get { + return source_id; + } + } + + public string Name { + get { + return name; + } + } + + /* This gives the full path of the source/ directory */ + public string BaseFilePath { + get { + return basePath; + } + } + + public TraceLevel TraceLevel { + get; + set; + } + + public string BaseDir { + get { + return basePath; + } + } + + public Tree Tree { + get { + return tree; + } + } + + public RootTree RootTree { + get { + return rootTree; + } + set { + rootTree = value; + } + } + + public IDocCache Cache { + get { + return cache; + } + } + + public IDocStorage Storage { + get { + return storage; + } + } + + // A HelpSource may have a common prefix to its URL, give it here + protected virtual string UriPrefix { + get { + return "dummy:"; + } + } + + /// + /// Returns a stream from the packaged help source archive + /// + public virtual Stream GetHelpStream (string id) + { + return storage.Retrieve (id); + } + + public virtual Stream GetCachedHelpStream (string id) + { + if (string.IsNullOrEmpty (id)) + throw new ArgumentNullException ("id"); + if (!cache.CanCache (DocEntity.Text)) + return GetHelpStream (id); + if (!cache.IsCached (id)) + cache.CacheText (id, GetHelpStream (id)); + return cache.GetCachedStream (id); + } + + public XmlReader GetHelpXml (string id) + { + var url = "monodoc:///" + SourceID + "@" + Uri.EscapeDataString (id) + "@"; + var stream = cache.IsCached (id) ? cache.GetCachedStream (id) : storage.Retrieve (id); + + return stream == null ? null : new XmlTextReader (url, stream); + } + + public virtual XmlDocument GetHelpXmlWithChanges (string id) + { + XmlDocument doc = new XmlDocument (); + if (!storage.SupportRevision) { + doc.Load (GetHelpXml (id)); + } else { + var revManager = storage.RevisionManager; + doc.Load (revManager.RetrieveLatestRevision (id)); + } + return doc; + } + + public virtual string GetCachedText (string id) + { + if (!cache.CanCache (DocEntity.Text)) + return GetText (id); + if (!cache.IsCached (id)) + cache.CacheText (id, GetText (id)); + return cache.GetCachedString (id); + } + + public virtual string GetText (string id) + { + return new StreamReader (GetHelpStream (id)).ReadToEnd (); + } + + // Tells if the result for the provided id is generated dynamically + // by the help source + public virtual bool IsGeneratedContent (string id) + { + return false; + } + + // Tells if the content of the provided id is meant to be returned raw + public virtual bool IsRawContent (string id) + { + return false; + } + + // Tells if provided id refers to a multi-content-type document if it's case + // tells the ids it's formed of + public virtual bool IsMultiPart (string id, out IEnumerable parts) + { + parts = null; + return false; + } + + /// + /// Saves the tree and the archive + /// + public void Save () + { + tree.Save (treeFilePath); + storage.Dispose (); + } + + public virtual void RenderPreviewDocs (XmlNode newNode, XmlWriter writer) + { + throw new NotImplementedException (); + } + + public virtual string GetPublicUrl (Node node) + { + return node.GetInternalUrl (); + } + + public virtual bool CanHandleUrl (string url) + { + return url.StartsWith (UriPrefix, StringComparison.OrdinalIgnoreCase); + } + + public virtual string GetInternalIdForUrl (string url, out Node node) + { + node = MatchNode (url); + return node == null ? null : url.Substring (UriPrefix.Length); + } + + public virtual Node MatchNode (string url) + { + Node current = null; + + var matchCache = LRUCache.Default; + if ((current = matchCache.Get (url)) != null) + return current; + + current = Tree.RootNode; + var strippedUrl = url.StartsWith (UriPrefix, StringComparison.OrdinalIgnoreCase) ? url.Substring (UriPrefix.Length) : url; + var searchNode = new Node () { Element = strippedUrl }; + + do { + int index = current.Nodes.BinarySearch (searchNode, NodeElementComparer.Instance); + if (index >= 0) { + Node n = current.Nodes[index]; + //Console.WriteLine ("Binarysearch success for {0} which fell on {1}", strippedUrl, n.Element); + matchCache.Put (url, n); + return n; + } + index = ~index; + if (index == current.Nodes.Count) { + //Console.WriteLine ("Match fail for {0}", strippedUrl); + //Console.WriteLine (current.Nodes.Select (n => n.Element).Aggregate ((e1, e2) => e1 + ", " + e2)); + return SlowMatchNode (Tree.RootNode, matchCache, strippedUrl); + } + current = current.Nodes [index - 1]; + //Console.WriteLine ("Binarysearch failed for {0}, next node check is {1}", strippedUrl, current.Element); + } while (true); + + return null; + } + + /* That slow path is mainly here to handle ecmaspec type of url which are composed of hard to sort numbers + * because they don't have the same amount of digit. We could use a regex to harmonise the various number + * parts but then it would be quite specific. Since in the case of ecmaspec the tree is well-formed enough + * the "Slow" match should still be fast enough + */ + Node SlowMatchNode (Node current, LRUCache matchCache, string url) + { + //Console.WriteLine ("Entering slow path for {0} starting from {1}", url, current.Element); + while (current != null) { + bool stop = true; + foreach (Node n in current.Nodes) { + var element = n.Element.StartsWith (UriPrefix, StringComparison.OrdinalIgnoreCase) ? n.Element.Substring (UriPrefix.Length) : n.Element; + if (url == element) { + matchCache.Put (url, n); + return n; + } else if (url.StartsWith (element + ".", StringComparison.OrdinalIgnoreCase) && !n.IsLeaf) { + current = n; + stop = false; + break; + } + } + if (stop) + current = null; + } + + return null; + } + + class NodeElementComparer : IComparer + { + public static NodeElementComparer Instance = new NodeElementComparer (); + + public int Compare (Node n1, Node n2) + { + return string.Compare (Cleanup (n1), Cleanup (n2), StringComparison.Ordinal); + } + + string Cleanup (Node n) + { + var prefix = n.Tree != null && n.Tree.HelpSource != null ? n.Tree.HelpSource.UriPrefix : string.Empty; + var element = n.Element.StartsWith (prefix, StringComparison.OrdinalIgnoreCase) ? n.Element.Substring (prefix.Length) : n.Element; + if (char.IsDigit (element, 0)) { + var count = element.TakeWhile (char.IsDigit).Count (); + element = element.PadLeft (Math.Max (0, 3 - count) + element.Length, '0'); + } + //Console.WriteLine ("Cleaned up {0} to {1}", n.Element, element); + return element; + } + } + + public virtual DocumentType GetDocumentTypeForId (string id, out Dictionary extraParams) + { + extraParams = null; + return DocumentType.PlainText; + } + + public virtual Stream GetImage (string url) + { + return null; + } + + // + // Populates the index. + // + public virtual void PopulateIndex (IndexMaker index_maker) + { + } + + // + // Create different Documents for adding to Lucene search index + // The default action is do nothing. Subclasses should add the docs + // + public virtual void PopulateSearchableIndex (IndexWriter writer) + { + + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/Node.cs b/mcs/tools/monkeydoc/Monkeydoc/Node.cs new file mode 100644 index 00000000000..8d9bd1ea25a --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/Node.cs @@ -0,0 +1,323 @@ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Xml; +using System.Collections.Generic; + +namespace MonkeyDoc +{ + public class Node : IComparable, IComparable + { + readonly Tree tree; + string caption, element, pubUrl; + public bool Documented; + bool loaded; + Node parent; + List nodes; + Dictionary childrenLookup; + /* Address has three types of value, + * _ 0 is for no on-disk representation + * _ >0 is a valid address that is loaded immediately + * _ <0 is a valid negated address to indicate lazy loading + */ + int address; + + public Node (Node parent, string caption, string element) : this (parent.Tree, caption, element) + { + this.parent = parent; + } + + internal Node (Tree tree, string caption, string element) + { + this.tree = tree; + this.caption = caption; + this.element = element; + } + + /// + /// Creates a node from an on-disk representation + /// + internal Node (Node parent, int address) : this (parent.tree, address) + { + this.parent = parent; + } + + internal Node (Tree tree, int address) + { + this.address = address; + this.tree = tree; + if (address > 0) + LoadNode (); + } + + /* This is solely used for MatchNode to check for equality */ + internal Node () + { + } + + void LoadNode () + { + tree.InflateNode (this); + if (parent != null) + parent.RegisterFullNode (this); + } + + public void AddNode (Node n) + { + nodes.Add (n); + n.parent = this; + n.Documented = true; + RegisterFullNode (n); + } + + public void DeleteNode (Node n) + { + nodes.Remove (n); + if (!string.IsNullOrEmpty (n.element)) + childrenLookup.Remove (n.element); + } + + // When a child node is inflated, it calls this method + // so that we can add it to our lookup for quick search + void RegisterFullNode (Node child) + { + if (childrenLookup == null) + childrenLookup = new Dictionary (); + if (!string.IsNullOrEmpty (child.element)) + childrenLookup[child.element] = child; + } + + public List Nodes { + get { + EnsureLoaded (); + return nodes != null ? nodes : new List (); + } + } + + public string Element { + get { + EnsureLoaded (); + return element; + } + set { + element = value; + } + } + + public string Caption { + get { + EnsureLoaded (); + return caption; + } + internal set { + caption = value; + } + } + + public Node Parent { + get { + return parent; + } + } + + public Tree Tree { + get { + return tree; + } + } + + internal int Address { + get { + return address; + } + } + + /// + /// Creates a new node, in the locator entry point, and with + /// a user visible caption of @caption + /// + public Node CreateNode (string c_caption, string c_element) + { + EnsureNodes (); + if (string.IsNullOrEmpty (c_caption)) + throw new ArgumentNullException ("c_caption"); + if (string.IsNullOrEmpty (c_element)) + throw new ArgumentNullException ("c_element"); + + Node t = new Node (this, c_caption, c_element); + nodes.Add (t); + childrenLookup[c_element] = t; + + return t; + } + + public Node GetOrCreateNode (string c_caption, string c_element) + { + if (nodes == null) + return CreateNode (c_caption, c_element); + if (childrenLookup.Count != nodes.Count || (nodes.Count == 0 && childrenLookup.Count != nodes.Capacity)) + UpdateLookup (); + + Node result; + if (!childrenLookup.TryGetValue (c_element, out result)) + result = CreateNode (c_caption, c_element); + return result; + } + + public void EnsureNodes () + { + if (nodes == null) { + nodes = new List (); + childrenLookup = new Dictionary (); + } + } + + public void EnsureLoaded () + { + if (address < 0 && !loaded) { + LoadNode (); + loaded = true; + } + } + + void UpdateLookup () + { + foreach (var node in nodes) + childrenLookup[node.Element] = node; + } + + public bool IsLeaf { + get { + return nodes == null || nodes.Count == 0; + } + } + + void EncodeInt (BinaryWriter writer, int value) + { + do { + int high = (value >> 7) & 0x01ffffff; + byte b = (byte)(value & 0x7f); + + if (high != 0) { + b = (byte)(b | 0x80); + } + + writer.Write(b); + value = high; + } while(value != 0); + } + + int DecodeInt (BinaryReader reader) + { + int ret = 0; + int shift = 0; + byte b; + + do { + b = reader.ReadByte(); + + ret = ret | ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) == 0x80); + + return ret; + } + + internal void Deserialize (BinaryReader reader) + { + int count = DecodeInt (reader); + element = reader.ReadString (); + caption = reader.ReadString (); + + if (count == 0) + return; + + nodes = new List (count); + for (int i = 0; i < count; i++) { + int child_address = DecodeInt (reader); + + Node t = new Node (this, -child_address); + nodes.Add (t); + } + } + + internal void Serialize (FileStream output, BinaryWriter writer) + { + if (nodes != null) + foreach (Node child in nodes) + child.Serialize (output, writer); + + address = (int) output.Position; + EncodeInt (writer, nodes == null ? 0 : (int) nodes.Count); + writer.Write (element); + writer.Write (caption); + + if (nodes != null) + foreach (Node child in nodes) + EncodeInt (writer, child.address); + } + + public void Sort () + { + if (nodes != null) + nodes.Sort (); + } + + internal string GetInternalUrl () + { + EnsureLoaded (); + if (element.IndexOf (":") != -1 || parent == null) + return element; + + var parentUrl = parent.GetInternalUrl (); + return parentUrl.EndsWith ("/") ? parentUrl + element : parentUrl + "/" + element; + } + + public string PublicUrl { + get { + if (pubUrl != null) + return pubUrl; + return pubUrl = tree.HelpSource != null ? tree.HelpSource.GetPublicUrl (this) : GetInternalUrl (); + } + } + + int IComparable.CompareTo (object obj) + { + Node other = obj as Node; + if (other == null) + return -1; + return CompareToInternal (other); + } + + int IComparable.CompareTo (Node obj) + { + return CompareToInternal (obj); + } + + int CompareToInternal (Node other) + { + EnsureLoaded (); + other.EnsureLoaded (); + + var cap1 = caption; + var cap2 = other.caption; + + /* Some node (notably from ecmaspec) have number prepended to them + * which we need to sort better by padding them to the same number + * of digits + */ + if (char.IsDigit (cap1[0]) && char.IsDigit (cap2[0])) { + int c1 = cap1.TakeWhile (char.IsDigit).Count (); + int c2 = cap2.TakeWhile (char.IsDigit).Count (); + + if (c1 != c2) { + cap1 = cap1.PadLeft (cap1.Length + Math.Max (0, c2 - c1), '0'); + cap2 = cap2.PadLeft (cap2.Length + Math.Max (0, c1 - c2), '0'); + } + } + + return string.Compare (cap1, cap2, StringComparison.Ordinal); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/Provider.cs b/mcs/tools/monkeydoc/Monkeydoc/Provider.cs new file mode 100644 index 00000000000..03c54e59b6c --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/Provider.cs @@ -0,0 +1,27 @@ +using System; + +namespace MonkeyDoc +{ + public abstract class Provider + { + // + // This code is used to "tag" all the different sources + // + static short serial; + + public int Code { get; set; } + + public Provider () + { + Code = serial++; + } + + public abstract void PopulateTree (Tree tree); + + // + // Called at shutdown time after the tree has been populated to perform + // any fixups or final tasks. + // + public abstract void CloseTree (HelpSource hs, Tree tree); + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/RootTree.cs b/mcs/tools/monkeydoc/Monkeydoc/RootTree.cs new file mode 100644 index 00000000000..daf745c32da --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/RootTree.cs @@ -0,0 +1,481 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Configuration; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Xml; + +using MonkeyDoc.Providers; +using Lucene.Net.Analysis.Standard; +using Lucene.Net.Index; + +namespace MonkeyDoc +{ + public class RootTree : Tree + { + public const int MonodocVersion = 2; + const string RootNamespace = "root:/"; + string basedir; + List uncompiledHelpSourcePaths = new List(); + HashSet loadedSourceFiles = new HashSet(); + List helpSources = new List(); + Dictionary nameToNode = new Dictionary(); + Dictionary nameToHelpSource = new Dictionary(); + + public IList HelpSources { + get { + return this.helpSources.AsReadOnly(); + } + } + + public DateTime LastHelpSourceTime { + get; + set; + } + + static bool IsUnix { + get { + int platform = (int)Environment.OSVersion.Platform; + return platform == 4 || platform == 128 || platform == 6; + } + } + + RootTree () : base (null, "Mono Documentation", "root:") + { + base.RootNode.EnsureNodes(); + this.LastHelpSourceTime = DateTime.Now; + } + + public static RootTree LoadTree () + { + return RootTree.LoadTree (RootTree.ProbeBaseDirectories ()); + } + + static string ProbeBaseDirectories () + { + string result; + try { + NameValueCollection appSettings = ConfigurationManager.AppSettings; + result = appSettings["docPath"]; + } catch { + result = "."; + } + return result; + } + + public static RootTree LoadTree (string basedir, bool includeExternal = true) + { + if (string.IsNullOrEmpty (basedir)) + throw new ArgumentNullException ("basedir"); + if (!Directory.Exists (basedir)) + throw new ArgumentException ("basedir", string.Format ("Base documentation directory at '{0}' doesn't exist", basedir)); + + XmlDocument xmlDocument = new XmlDocument (); + string filename = Path.Combine (basedir, "monodoc.xml"); + xmlDocument.Load (filename); + IEnumerable sourceFiles = Directory.EnumerateFiles (Path.Combine (basedir, "sources"), "*.source"); + if (includeExternal) + sourceFiles = sourceFiles.Concat (RootTree.ProbeExternalDirectorySources ()); + return RootTree.LoadTree (basedir, xmlDocument, sourceFiles); + } + + static IEnumerable ProbeExternalDirectorySources () + { + IEnumerable enumerable = Enumerable.Empty (); + try { + string path = ConfigurationManager.AppSettings["docExternalPath"]; + enumerable = enumerable.Concat (System.IO.Directory.EnumerateFiles (path, "*.source")); + } + catch {} + + if (Directory.Exists ("/Library/Frameworks/Mono.framework/External/monodoc")) + enumerable = enumerable.Concat (Directory.EnumerateFiles ("/Library/Frameworks/Mono.framework/External/monodoc", "*.source")); + return enumerable; + } + + public static RootTree LoadTree (string indexDir, XmlDocument docTree, IEnumerable sourceFiles) + { + if (docTree == null) { + docTree = new XmlDocument (); + using (Stream manifestResourceStream = typeof (RootTree).Assembly.GetManifestResourceStream ("monodoc.xml")) { + docTree.Load (manifestResourceStream); + } + } + + sourceFiles = (sourceFiles ?? new string[0]); + RootTree rootTree = new RootTree (); + rootTree.basedir = indexDir; + XmlNodeList xml_node_list = docTree.SelectNodes ("/node/node"); + rootTree.nameToNode["root"] = rootTree.RootNode; + rootTree.nameToNode["libraries"] = rootTree.RootNode; + rootTree.Populate (rootTree.RootNode, xml_node_list); + + if (rootTree.LookupEntryPoint ("various") == null) { + Console.Error.WriteLine ("No 'various' doc node! Check monodoc.xml!"); + Node rootNode = rootTree.RootNode; + } + + foreach (string current in sourceFiles) + rootTree.AddSourceFile (current); + + RootTree.PurgeNode (rootTree.RootNode); + rootTree.RootNode.Sort (); + return rootTree; + } + + public void AddSource (string sourcesDir) + { + IEnumerable enumerable = Directory.EnumerateFiles (sourcesDir, "*.source"); + foreach (string current in enumerable) + if (!this.AddSourceFile (current)) + Console.Error.WriteLine ("Error: Could not load source file {0}", current); + } + + public bool AddSourceFile (string sourceFile) + { + if (this.loadedSourceFiles.Contains (sourceFile)) + return false; + + Node node = this.LookupEntryPoint ("various") ?? base.RootNode; + XmlDocument xmlDocument = new XmlDocument (); + try { + xmlDocument.Load (sourceFile); + } catch { + bool result = false; + return result; + } + + XmlNodeList extra_nodes = xmlDocument.SelectNodes ("/monodoc/node"); + if (extra_nodes.Count > 0) + this.Populate (node, extra_nodes); + + XmlNodeList sources = xmlDocument.SelectNodes ("/monodoc/source"); + if (sources == null) { + Console.Error.WriteLine ("Error: No section found in the {0} file", sourceFile); + return false; + } + + loadedSourceFiles.Add (sourceFile); + foreach (XmlNode xmlNode in sources) { + XmlAttribute a = xmlNode.Attributes["provider"]; + if (a == null) { + Console.Error.WriteLine ("Error: no provider in "); + continue; + } + string provider = a.InnerText; + a = xmlNode.Attributes["basefile"]; + if (a == null) { + Console.Error.WriteLine ("Error: no basefile in "); + continue; + } + string basefile = a.InnerText; + a = xmlNode.Attributes["path"]; + if (a == null) { + Console.Error.WriteLine ("Error: no path in "); + continue; + } + string path = a.InnerText; + string basefilepath = Path.Combine (Path.GetDirectoryName (sourceFile), basefile); + HelpSource helpSource = RootTree.GetHelpSource (provider, basefilepath); + if (helpSource != null) { + helpSource.RootTree = this; + this.helpSources.Add (helpSource); + this.nameToHelpSource[path] = helpSource; + Node node2 = this.LookupEntryPoint (path); + if (node2 == null) { + Console.Error.WriteLine ("node `{0}' is not defined on the documentation map", path); + node2 = node; + } + foreach (Node current in helpSource.Tree.RootNode.Nodes) { + node2.AddNode (current); + } + node2.Sort (); + } + } + return true; + } + + static bool PurgeNode (Node node) + { + bool result = false; + if (!node.Documented) + { + List list = new List (); + foreach (Node current in node.Nodes) + { + bool flag = RootTree.PurgeNode (current); + if (flag) + { + list.Add (current); + } + } + result = (node.Nodes.Count == list.Count); + foreach (Node current2 in list) + { + node.DeleteNode (current2); + } + } + return result; + } + + public static string[] GetSupportedFormats () + { + return new string[] + { + "ecma", + "ecmaspec", + "error", + "man", + "xhtml" + }; + } + + public static HelpSource GetHelpSource (string provider, string basefilepath) + { + HelpSource result; + try { + switch (provider) { + case "xhtml": + case "hb": + result = new XhtmlHelpSource (basefilepath, false); + break; + case "man": + result = new ManHelpSource (basefilepath, false); + break; + case "error": + result = new ErrorHelpSource (basefilepath, false); + break; + case "ecmaspec": + result = new EcmaSpecHelpSource (basefilepath, false); + break; + case "ecma": + result = new EcmaHelpSource (basefilepath, false); + break; + default: + Console.Error.WriteLine ("Error: Unknown provider specified: {0}", provider); + result = null; + break; + } + } catch (FileNotFoundException) { + Console.Error.WriteLine ("Error: did not find one of the files in sources/" + basefilepath); + result = null; + } + return result; + } + + public static Provider GetProvider (string provider, params string[] basefilepaths) + { + switch (provider) { + case "ecma": + return new EcmaProvider (basefilepaths[0]); + case "ecmaspec": + return new EcmaSpecProvider (basefilepaths[0]); + case "error": + return new ErrorProvider (basefilepaths[0]); + case "man": + return new ManProvider (basefilepaths); + case "xhml": + case "hb": + return new XhtmlProvider (basefilepaths[0]); + } + + throw new NotSupportedException (provider); + } + + void Populate (Node parent, XmlNodeList xml_node_list) + { + foreach (XmlNode xmlNode in xml_node_list) { + XmlAttribute e = xmlNode.Attributes["parent"]; + Node parent2 = null; + if (e != null && this.nameToNode.TryGetValue (e.InnerText, out parent2)) { + xmlNode.Attributes.Remove (e); + Populate (parent2, xmlNode.SelectNodes (".")); + continue; + } + e = xmlNode.Attributes["label"]; + if (e == null) { + Console.Error.WriteLine ("`label' attribute missing in "); + continue; + } + string label = e.InnerText; + e = xmlNode.Attributes["name"]; + if (e == null) { + Console.Error.WriteLine ("`name' attribute missing in "); + continue; + } + string name = e.InnerText; + Node orCreateNode = parent.GetOrCreateNode (label, "root:/" + name); + orCreateNode.EnsureNodes (); + this.nameToNode[name] = orCreateNode; + XmlNodeList xmlNodeList = xmlNode.SelectNodes ("./node"); + if (xmlNodeList != null) { + this.Populate (orCreateNode, xmlNodeList); + } + } + } + + public Node LookupEntryPoint (string name) + { + Node result = null; + if (!this.nameToNode.TryGetValue (name, out result)) { + result = null; + } + return result; + } + + public TOutput RenderUrl (string url, IDocGenerator generator, out Node node) + { + node = null; + string internalId = null; + HelpSource hs = GetHelpSourceAndIdForUrl (url, out internalId, out node); + return generator.Generate (hs, internalId); + } + + public HelpSource GetHelpSourceAndIdForUrl (string url, out string internalId, out Node node) + { + node = null; + internalId = null; + + if (url.StartsWith ("root:/", StringComparison.OrdinalIgnoreCase)) + return this.GetHelpSourceAndIdFromName (url.Substring ("root:/".Length), out internalId, out node); + + HelpSource helpSource = null; + foreach (var hs in helpSources.Where (h => h.CanHandleUrl (url))) { + if (!string.IsNullOrEmpty (internalId = hs.GetInternalIdForUrl (url, out node))) { + helpSource = hs; + break; + } + } + + return helpSource; + } + + public HelpSource GetHelpSourceAndIdFromName (string name, out string internalId, out Node node) + { + internalId = "root:"; + node = this.LookupEntryPoint (name); + + return node == null ? null : node.Nodes.Select (n => n.Tree.HelpSource).Where (hs => hs != null).Distinct ().FirstOrDefault (); + } + + public HelpSource GetHelpSourceFromId (int id) + { + return (id < 0 || id >= this.helpSources.Count) ? null : this.helpSources[id]; + } + + public Stream GetImage (string url) + { + if (url.StartsWith ("source-id:", StringComparison.OrdinalIgnoreCase)) { + string text = url.Substring (10); + int num = text.IndexOf (":"); + string text2 = text.Substring (0, num); + int id = 0; + try { + id = int.Parse (text2); + } catch { + Console.Error.WriteLine ("Failed to parse source-id url: {0} `{1}'", url, text2); + return null; + } + HelpSource helpSourceFromId = this.GetHelpSourceFromId (id); + return helpSourceFromId.GetImage (text.Substring (num + 1)); + } + Assembly assembly = Assembly.GetAssembly (typeof (RootTree)); + return assembly.GetManifestResourceStream (url); + } + + public IndexReader GetIndex () + { + string text = Path.Combine (this.basedir, "monodoc.index"); + if (File.Exists (text)) + { + return IndexReader.Load (text); + } + text = Path.Combine (ConfigurationManager.AppSettings["monodocIndexDirectory"], "monodoc.index"); + return IndexReader.Load (text); + } + + public static void MakeIndex () + { + RootTree rootTree = RootTree.LoadTree (); + rootTree.GenerateIndex (); + } + + public void GenerateIndex () + { + IndexMaker indexMaker = new IndexMaker (); + foreach (HelpSource current in this.helpSources) + current.PopulateIndex (indexMaker); + string text = Path.Combine (this.basedir, "monodoc.index"); + try { + indexMaker.Save (text); + } catch (UnauthorizedAccessException) { + text = Path.Combine (ConfigurationManager.AppSettings["docDir"], "monodoc.index"); + try { + indexMaker.Save (text); + } catch (UnauthorizedAccessException) { + Console.WriteLine ("Unable to write index file in {0}", Path.Combine (ConfigurationManager.AppSettings["docDir"], "monodoc.index")); + return; + } + } + if (RootTree.IsUnix) + RootTree.chmod (text, 420); + + Console.WriteLine ("Documentation index at {0} updated", text); + } + + public SearchableIndex GetSearchIndex () + { + string text = Path.Combine (this.basedir, "search_index"); + if (System.IO.Directory.Exists (text)) { + return SearchableIndex.Load (text); + } + text = Path.Combine (ConfigurationManager.AppSettings["docDir"], "search_index"); + return SearchableIndex.Load (text); + } + + public static void MakeSearchIndex () + { + RootTree rootTree = RootTree.LoadTree (); + rootTree.GenerateSearchIndex (); + } + + public void GenerateSearchIndex () + { + Console.WriteLine ("Loading the monodoc tree..."); + string text = Path.Combine (this.basedir, "search_index"); + IndexWriter indexWriter; + var analyzer = new StandardAnalyzer (Lucene.Net.Util.Version.LUCENE_CURRENT); + var directory = Lucene.Net.Store.FSDirectory.Open (text); + + try { + if (!Directory.Exists (text)) + Directory.CreateDirectory (text); + indexWriter = new IndexWriter (directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED); + } catch (UnauthorizedAccessException) { + try { + text = Path.Combine (ConfigurationManager.AppSettings["docDir"], "search_index"); + if (!Directory.Exists (text)) + Directory.CreateDirectory (text); + indexWriter = new IndexWriter (directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED); + } catch (UnauthorizedAccessException) { + Console.WriteLine ("You don't have permissions to write on " + text); + return; + } + } + Console.WriteLine ("Collecting and adding documents..."); + foreach (HelpSource current in this.helpSources) { + current.PopulateSearchableIndex (indexWriter); + } + Console.WriteLine ("Closing..."); + indexWriter.Optimize (); + indexWriter.Close (); + } + + [DllImport ("libc")] + static extern int chmod (string filename, int mode); + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/SearchableDocument.cs b/mcs/tools/monkeydoc/Monkeydoc/SearchableDocument.cs new file mode 100644 index 00000000000..6c2bacc283d --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/SearchableDocument.cs @@ -0,0 +1,43 @@ +// +// +// SearchableDocument.cs: Abstracts our model of document from the Lucene Document +// +// Author: Mario Sopena +// +using Lucene.Net.Documents; + +namespace MonkeyDoc +{ + struct SearchableDocument + { + public string title; + public string url; + public string fulltitle; + public string hottext; + public string text; + public string examples; + + public Document LuceneDoc { + get { + Document doc = new Document (); + doc.Add (UnIndexed ("title", title)); + doc.Add (UnIndexed ("url", url)); + doc.Add (UnIndexed ("fulltitle", fulltitle ?? string.Empty)); + doc.Add (UnStored ("hottext", hottext)); + doc.Add (UnStored ("text", text)); + doc.Add (UnStored ("examples", examples)); + return doc; + } + } + + static Field UnIndexed(System.String name, System.String value_Renamed) + { + return new Field(name, value_Renamed, Field.Store.YES, Field.Index.NO); + } + + static Field UnStored(System.String name, System.String value_Renamed) + { + return new Field(name, value_Renamed, Field.Store.NO, Field.Index.ANALYZED); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/SearchableIndex.cs b/mcs/tools/monkeydoc/Monkeydoc/SearchableIndex.cs new file mode 100644 index 00000000000..6ad2a652ce4 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/SearchableIndex.cs @@ -0,0 +1,190 @@ +// +// +// SearchableIndex.cs: Index that uses Lucene to search through the docs +// +// Author: Mario Sopena +// + +using System; +using System.IO; +using System.Collections; +// Lucene imports +using Lucene.Net.Index; +using Lucene.Net.Documents; +using Lucene.Net.Analysis; +using Lucene.Net.Analysis.Standard; +using Lucene.Net.Search; +using Lucene.Net.QueryParsers; +using Lucene.Net.Store; + +namespace MonkeyDoc +{ + public class SearchableIndex + { + const int maxSearchCount = 30; + + IndexSearcher searcher; + string dir; + public string Dir { + get { + if (dir == null) dir = "search_index"; + return dir; + } + set { dir = value; } + } + public ArrayList Results; + + public static SearchableIndex Load (string dir) { + SearchableIndex s = new SearchableIndex (); + s.dir = dir; + s.Results = new ArrayList (20); + try { + //s.searcher = new IndexSearcher (dir); + // TODO: parametrize that depending if we run on the desktop (low footprint) or the server (use RAMDirectory for instance) + s.searcher = new IndexSearcher (FSDirectory.Open (dir)); + } catch (IOException) { + Console.WriteLine ("Index nonexistent or in bad format"); + return null; + } + return s; + } + + // + // Search the index with term + // + + public Result Search (string term) + { + return Search (term, maxSearchCount); + } + + public Result Search (string term, int count) + { + return Search (term, count, 0); + } + + public Result Search (string term, int count, int start) { + try { + term = term.ToLower (); + Term htTerm = new Term ("hottext", term); + Query qq1 = new FuzzyQuery (htTerm); + Query qq2 = new TermQuery (htTerm); + qq2.Boost = 10f; + Query qq3 = new PrefixQuery (htTerm); + qq3.Boost = 10f; + DisjunctionMaxQuery q1 = new DisjunctionMaxQuery (0f); + q1.Add (qq1); + q1.Add (qq2); + q1.Add (qq3); + Query q2 = new TermQuery (new Term ("text", term)); + q2.Boost = 3f; + Query q3 = new TermQuery (new Term ("examples", term)); + q3.Boost = 3f; + DisjunctionMaxQuery q = new DisjunctionMaxQuery (0f); + + q.Add (q1); + q.Add (q2); + q.Add (q3); + + TopDocs top = SearchInternal (q, count, start); + Result r = new Result (term, searcher, top.ScoreDocs); + Results.Add (r); + return r; + } catch (IOException) { + Console.WriteLine ("No index in {0}", dir); + return null; + } + } + + TopDocs SearchInternal (Query q, int count, int start) + { + // Easy path that doesn't involve creating a Collector ourselves + // watch for Lucene.NET improvement on that (like searcher.SearchAfter) + if (start == 0) + return searcher.Search (q, count); + + var weight = searcher.CreateWeight (q); // TODO: reuse weight instead of query + var collector = TopScoreDocCollector.Create (start + count + 1, false); + searcher.Search (q, collector); + + return collector.TopDocs (start, count); + } + + public Result FastSearch (string term, int number) + { + try { + term = term.ToLower (); + Query q1 = new TermQuery (new Term ("hottext", term)); + Query q2 = new PrefixQuery (new Term ("hottext", term)); + q2.Boost = 0.5f; + DisjunctionMaxQuery q = new DisjunctionMaxQuery (0f); + q.Add (q1); + q.Add (q2); + TopDocs top = searcher.Search (q, number); + return new Result (term, searcher, top.ScoreDocs); + } catch (IOException) { + Console.WriteLine ("No index in {0}", dir); + return null; + } + } + + Query Parse (string term, string field, bool fuzzy) + { + QueryParser parser = new QueryParser (Lucene.Net.Util.Version.LUCENE_CURRENT, + field, + new StandardAnalyzer (Lucene.Net.Util.Version.LUCENE_CURRENT)); + return parser.Parse (term); + } + } + // + // An object representing the search term with the results + // + public class Result { + string term; + Searcher searcher; + ScoreDoc[] docs; + + public string Term { + get { return term;} + } + + public int Count { + get { return docs.Length; } + } + + public Document this [int i] { + get { return searcher.Doc (docs[i].Doc); } + } + + public string GetTitle (int i) + { + Document d = this[i]; + return d == null ? string.Empty : d.Get ("title"); + } + + public string GetUrl (int i) + { + Document d = this[i]; + return d == null ? string.Empty : d.Get ("url"); + } + + public string GetFullTitle (int i) + { + Document d = this[i]; + return d == null ? string.Empty : d.Get ("fulltitle"); + } + + public float Score (int i) + { + return docs[i].Score; + } + + public Result (string Term, Searcher searcher, ScoreDoc[] docs) + { + this.term = Term; + this.searcher = searcher; + this.docs = docs; + } + } +} + diff --git a/mcs/tools/monkeydoc/Monkeydoc/Tree.cs b/mcs/tools/monkeydoc/Monkeydoc/Tree.cs new file mode 100644 index 00000000000..a9b33672af8 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/Tree.cs @@ -0,0 +1,164 @@ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Xml; +using System.Collections.Generic; + +namespace MonkeyDoc +{ + /// + /// This tree is populated by the documentation providers, or populated + /// from a binary encoding of the tree. The format of the tree is designed + /// to minimize the need to load it in full. + /// + + /* Ideally this class should also be abstracted to let user have something + * else than a file as a backing store, a database for instance + */ + public class Tree + { + public readonly HelpSource HelpSource; + + FileStream InputStream; + BinaryReader InputReader; + + // This is the node which contains all the other node of the tree + Node rootNode; + + /// + /// Load from file constructor + /// + public Tree (HelpSource hs, string filename) + { + Encoding utf8 = new UTF8Encoding (false, true); + + if (!File.Exists (filename)){ + throw new FileNotFoundException (); + } + + InputStream = File.OpenRead (filename); + InputReader = new BinaryReader (InputStream, utf8); + byte [] sig = InputReader.ReadBytes (4); + + if (!GoodSig (sig)) + throw new Exception ("Invalid file format"); + + InputStream.Position = 4; + var position = InputReader.ReadInt32 (); + rootNode = new Node (this, position); + InflateNode (rootNode); + + HelpSource = hs; + } + + /// + /// Tree creation and merged tree constructor + /// + public Tree (HelpSource hs, string caption, string url) : this (hs, null, caption, url) + { + } + + public Tree (HelpSource hs, Node parent, string caption, string element) + { + HelpSource = hs; + rootNode = parent == null ? new Node (this, caption, element) : new Node (parent, caption, element); + } + + /// + /// Saves the tree into the specified file using the help file format. + /// + public void Save (string file) + { + Encoding utf8 = new UTF8Encoding (false, true); + using (FileStream output = File.OpenWrite (file)){ + // Skip over the pointer to the first node. + output.Position = 8; + + using (BinaryWriter writer = new BinaryWriter (output, utf8)) { + // Recursively dump + rootNode.Serialize (output, writer); + + output.Position = 0; + writer.Write (new byte [] { (byte) 'M', (byte) 'o', (byte) 'H', (byte) 'P' }); + writer.Write (rootNode.Address); + } + } + } + + public Node RootNode { + get { + return rootNode; + } + } + + static bool GoodSig (byte [] sig) + { + if (sig.Length != 4) + return false; + return sig [0] == (byte) 'M' + && sig [1] == (byte) 'o' + && sig [2] == (byte) 'H' + && sig [3] == (byte) 'P'; + } + + public void InflateNode (Node baseNode) + { + var address = baseNode.Address; + if (address < 0) + address = -address; + + InputStream.Position = address; + baseNode.Deserialize (InputReader); + } + } + + public static class TreeDumper + { + static int indent; + + static void Indent () + { + for (int i = 0; i < indent; i++) + Console.Write (" "); + } + + public static void PrintTree (Node node) + { + Indent (); + Console.WriteLine ("{0},{1}\t[PublicUrl: {2}]", node.Element, node.Caption, node.PublicUrl); + if (node.Nodes.Count == 0) + return; + + indent++; + foreach (Node n in node.Nodes) + PrintTree (n); + indent--; + } + + public static string ExportToTocXml (Node root, string title, string desc) + { + if (root == null) + throw new ArgumentNullException ("root"); + // Return a toc index of sub-nodes + StringBuilder buf = new StringBuilder (); + var writer = XmlWriter.Create (buf); + writer.WriteStartElement ("toc"); + writer.WriteAttributeString ("title", title ?? string.Empty); + writer.WriteElementString ("description", desc ?? string.Empty); + writer.WriteStartElement ("list"); + foreach (Node n in root.Nodes) { + writer.WriteStartElement ("item"); + writer.WriteAttributeString ("url", n.Element); + writer.WriteValue (n.Caption); + writer.WriteEndElement (); + } + writer.WriteEndElement (); + writer.WriteEndElement (); + writer.Flush (); + writer.Close (); + + return buf.ToString (); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/TypeUtils.cs b/mcs/tools/monkeydoc/Monkeydoc/TypeUtils.cs new file mode 100644 index 00000000000..2e756630a52 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/TypeUtils.cs @@ -0,0 +1,40 @@ +using System; + +namespace MonkeyDoc +{ + public static class TypeUtils + { + public static bool GetNamespaceAndType (string url, out string ns, out string type) + { + int nsidx = -1; + int numLt = 0; + for (int i = 0; i < url.Length; ++i) { + char c = url [i]; + switch (c) { + case '<': + case '{': + ++numLt; + break; + case '>': + case '}': + --numLt; + break; + case '.': + if (numLt == 0) + nsidx = i; + break; + } + } + + if (nsidx == -1) { + ns = null; + type = null; + return false; + } + ns = url.Substring (0, nsidx); + type = url.Substring (nsidx + 1); + + return true; + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/cache.cs b/mcs/tools/monkeydoc/Monkeydoc/cache.cs new file mode 100644 index 00000000000..2c089bebd9b --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/cache.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; + +namespace MonkeyDoc +{ + public enum DocEntity + { + Text, + Blob + } + + public interface IDocCache : IDisposable + { + bool IsCached (string id); + bool CanCache (DocEntity entity); + + Stream GetCachedStream (string id); + string GetCachedString (string id); + + void CacheText (string id, string content); + void CacheText (string id, Stream stream); + + void CacheBlob (string id, byte[] data); + void CacheBlob (string id, Stream stream); + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/caches/FileCache.cs b/mcs/tools/monkeydoc/Monkeydoc/caches/FileCache.cs new file mode 100644 index 00000000000..333f33b44a2 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/caches/FileCache.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; + +namespace MonkeyDoc.Caches +{ + public class FileCache : IDocCache + { + string baseCacheDir; + + public FileCache (string baseCacheDir) + { + this.baseCacheDir = baseCacheDir; + if (!Directory.Exists (baseCacheDir)) + Directory.CreateDirectory (baseCacheDir); + } + + public bool IsCached (string id) + { + return File.Exists (MakePath (id)); + } + + public bool CanCache (DocEntity entity) + { + return true; + } + + public Stream GetCachedStream (string id) + { + return File.OpenRead (MakePath (id)); + } + + public string GetCachedString (string id) + { + return File.ReadAllText (MakePath (id)); + } + + public void CacheText (string id, string content) + { + File.WriteAllText (MakePath (id), content); + } + + public void CacheText (string id, Stream stream) + { + using (var file = File.OpenWrite (MakePath (id))) + stream.CopyTo (file); + } + + public void CacheBlob (string id, byte[] data) + { + File.WriteAllBytes (MakePath (id), data); + } + + public void CacheBlob (string id, Stream stream) + { + using (var file = File.OpenWrite (MakePath (id))) + stream.CopyTo (file); + } + + string MakePath (string id) + { + id = id.Replace (Path.DirectorySeparatorChar, '_'); + return Path.Combine (baseCacheDir, id); + } + + public void Dispose () + { + if (!Directory.Exists (baseCacheDir)) + return; + + try { + Directory.Delete (baseCacheDir, true); + } catch {} + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/caches/NullCache.cs b/mcs/tools/monkeydoc/Monkeydoc/caches/NullCache.cs new file mode 100644 index 00000000000..1514d661d53 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/caches/NullCache.cs @@ -0,0 +1,54 @@ +using System; +using System.IO; + +namespace MonkeyDoc.Caches +{ + // This is basically a no-cache implementation + public class NullCache : IDocCache + { + public bool IsCached (string id) + { + return false; + } + + public bool CanCache (DocEntity entity) + { + return false; + } + + public Stream GetCachedStream (string id) + { + return null; + } + + public string GetCachedString (string id) + { + return null; + } + + public void CacheText (string id, string content) + { + + } + + public void CacheText (string id, Stream stream) + { + + } + + public void CacheBlob (string id, byte[] data) + { + + } + + public void CacheBlob (string id, Stream stream) + { + + } + + public void Dispose () + { + + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generator.cs b/mcs/tools/monkeydoc/Monkeydoc/generator.cs new file mode 100644 index 00000000000..f0949b9d686 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generator.cs @@ -0,0 +1,27 @@ +using System; + +namespace MonkeyDoc +{ + // All type of documents that a generator may find as input + public enum DocumentType { + EcmaXml, // Our main monodoc format + EcmaSpecXml, + Man, + AddinXml, + MonoBook, // This is mostly XHTML already, just need a tiny bit of processing + Html, + TocXml, // Used by help source displaying some kind of toc of the content they host + PlainText, + ErrorXml + } + + /* This interface defines a set of transformation engine + * that convert multiple documentation source to a single output format + */ + public interface IDocGenerator + { + // This method is responsible for finding out the documentation type + // for the given ID and use the right engine internally + TOutput Generate (HelpSource hs, string internalId); + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/HtmlGenerator.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/HtmlGenerator.cs new file mode 100644 index 00000000000..553a1877460 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/HtmlGenerator.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Collections.Generic; + +using MonkeyDoc; + +namespace MonkeyDoc.Generators +{ + using Html; + + interface IHtmlExporter + { + string CssCode { get; } + string Export (Stream input, Dictionary extras); + string Export (string input, Dictionary extras); + } + + public class HtmlGenerator : IDocGenerator + { + const string cachePrefix = "htmlcached#"; + + static string css_code; + + IDocCache defaultCache; + static Dictionary converters; + + static HtmlGenerator () + { + converters = new Dictionary { + { DocumentType.EcmaXml, new Ecma2Html () }, + { DocumentType.Man, new Man2Html () }, + { DocumentType.TocXml, new Toc2Html () }, + { DocumentType.EcmaSpecXml, new Ecmaspec2Html () }, + { DocumentType.ErrorXml, new Error2Html () }, + { DocumentType.Html, new Idem () }, + { DocumentType.MonoBook, new MonoBook2Html () }, + { DocumentType.AddinXml, new Addin2Html () }, + { DocumentType.PlainText, new Idem () }, + }; + } + + public HtmlGenerator (IDocCache defaultCache) + { + this.defaultCache = defaultCache; + } + + public string Generate (HelpSource hs, string id) + { + if (hs == null || string.IsNullOrEmpty (id)) + return MakeHtmlError ("Your request has found no candidate provider"); + var cache = defaultCache ?? hs.Cache; + if (cache != null && cache.IsCached (MakeCacheKey (hs, id, null))) + return cache.GetCachedString (MakeCacheKey (hs, id, null)); + + IEnumerable parts; + if (hs.IsMultiPart (id, out parts)) + return GenerateMultiPart (hs, parts, id); + + if (hs.IsRawContent (id)) + return hs.GetText (id) ?? string.Empty; + + Dictionary extraParams = null; + DocumentType type = hs.GetDocumentTypeForId (id, out extraParams); + if (cache != null && extraParams != null && cache.IsCached (MakeCacheKey (hs, id, extraParams))) + return cache.GetCachedString (MakeCacheKey (hs, id, extraParams)); + + IHtmlExporter exporter; + if (!converters.TryGetValue (type, out exporter)) + return MakeHtmlError (string.Format ("Input type '{0}' not supported", + type.ToString ())); + var result = hs.IsGeneratedContent (id) ? + exporter.Export (hs.GetCachedText (id), extraParams) : + exporter.Export (hs.GetCachedHelpStream (id), extraParams); + + if (cache != null) + cache.CacheText (MakeCacheKey (hs, id, extraParams), result); + return result; + } + + string GenerateMultiPart (HelpSource hs, IEnumerable ids, string originalId) + { + var sb = new StringBuilder (); + foreach (var id in ids) + sb.AppendLine (Generate (hs, id)); + + var cache = defaultCache ?? hs.Cache; + if (cache != null) + cache.CacheText (MakeCacheKey (hs, originalId, null), sb.ToString ()); + return sb.ToString (); + } + + public static string InlineCss { + get { + if (css_code != null) + return css_code; + + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly (typeof (HtmlGenerator)); + Stream str_css = assembly.GetManifestResourceStream ("base.css"); + StringBuilder sb = new StringBuilder ((new StreamReader (str_css)).ReadToEnd()); + sb.Replace ("@@FONT_FAMILY@@", "Sans Serif"); + sb.Replace ("@@FONT_SIZE@@", "100%"); + css_code = sb.ToString () + converters.Values + .Select (c => c.CssCode) + .Where (css => !string.IsNullOrEmpty (css)) + .DefaultIfEmpty (string.Empty) + .Aggregate (string.Concat); + return css_code; + } + set { + css_code = value; + } + } + + string MakeHtmlError (string error) + { + return string.Format ("

{0}

", error); + } + + string MakeCacheKey (HelpSource hs, string page, IDictionary extraParams) + { + var key = cachePrefix + hs.SourceID + page; + if (extraParams != null && extraParams.Count > 0) { + var paramPart = string.Join ("-", extraParams.Select (kvp => kvp.Key + kvp.Value)); + key += '_' + paramPart; + } + return key; + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Addin2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Addin2Html.cs new file mode 100644 index 00000000000..3d37482a568 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Addin2Html.cs @@ -0,0 +1,197 @@ +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Xsl; +using System.Xml.XPath; +using System.Collections.Generic; + +namespace MonkeyDoc.Generators.Html +{ + public class Addin2Html : IHtmlExporter + { + public string CssCode { + get { + return string.Empty; + } + } + + public string Export (Stream stream, Dictionary extraArgs) + { + using (var reader = new StreamReader (stream)) + return Htmlize (GetAddin (reader, extraArgs["AddinID"]), + extraArgs["show"], + extraArgs["AddinID"], + extraArgs["FileID"], + extraArgs["NodeID"]); + } + + public string Export (string input, Dictionary extraArgs) + { + return Htmlize (GetAddin (new StringReader (input), extraArgs["AddinID"]), + extraArgs["show"], + extraArgs["AddinID"], + extraArgs["FileID"], + extraArgs["NodeID"]); + } + + XmlElement GetAddin (TextReader reader, string addinId) + { + XmlDocument doc = new XmlDocument (); + doc.Load (reader); + XmlElement addin = (XmlElement) doc.SelectSingleNode ("Addins/Addin[@fullId='" + addinId + "']"); + return addin != null ? addin : null; + } + + public string Htmlize (XmlElement addin, string urlType, string addinId, string fileId, string path) + { + if (urlType == MonkeyDoc.Providers.AddinsHelpSource.AddinPrefix) + return GetAddinTextFromUrl (addin, addinId, fileId); + else if (urlType == MonkeyDoc.Providers.AddinsHelpSource.ExtensionPrefix) + return GetExtensionTextFromUrl (addin, addinId, fileId, path); + else if (urlType == MonkeyDoc.Providers.AddinsHelpSource.ExtensionNodePrefix) + return GetExtensionNodeTextFromUrl (addin, addinId, fileId, path); + + return null; + } + + protected string GetAddinTextFromUrl (XmlElement addin, string addinId, string fileId) + { + if (addin == null) + return "Add-in not found: " + addinId + ""; + + StringBuilder sb = new StringBuilder (""); + sb.Append ("

").Append (addin.GetAttribute ("name")).Append ("

"); + XmlElement docs = (XmlElement) addin.SelectSingleNode ("Description"); + if (docs != null) + sb.Append (docs.InnerText); + + sb.Append ("

"); + sb.AppendFormat ("", addin.GetAttribute ("addinId")); + sb.AppendFormat ("", addin.GetAttribute ("namespace")); + sb.AppendFormat ("", addin.GetAttribute ("version")); + sb.Append ("
Id{0}
Namespace{0}
Version{0}

"); + sb.Append ("

Extension Points:

"); + sb.Append (""); + + sb.Append (""); + return sb.ToString (); + } + + protected string GetExtensionTextFromUrl (XmlElement addin, string addinId, string fileId, string path) + { + if (addin == null) + return "Add-in not found: " + addinId + ""; + + XmlElement ext = (XmlElement) addin.SelectSingleNode ("ExtensionPoint[@path='" + path + "']"); + if (ext == null) + return "Extension point not found: " + path + ""; + + StringBuilder sb = new StringBuilder (""); + sb.Append ("

").Append (ext.GetAttribute ("name")).Append ("

"); + + path = path.Replace ("/", " / "); + sb.Append ("

Path: ").Append (path).Append ("

"); + XmlElement desc = (XmlElement) ext.SelectSingleNode ("Description"); + if (desc != null) + sb.Append (desc.InnerText); + + sb.Append ("

Extension Nodes:

"); + sb.Append (""); + + foreach (XmlElement en in ext.SelectNodes ("ExtensionNode")) { + string nid = en.GetAttribute ("id"); + string nname = en.GetAttribute ("name"); + string sdesc = ""; + desc = (XmlElement) en.SelectSingleNode ("Description"); + if (desc != null) + sdesc = desc.InnerText; + + sb.AppendFormat ("", fileId, addinId, nid, nname, sdesc); + } + sb.Append ("
{3}{4}
"); + + sb.Append (""); + return sb.ToString (); + } + + protected string GetExtensionNodeTextFromUrl (XmlElement addin, string addinId, string fileId, string nodeId) + { + if (addin == null) + return "Add-in not found: " + addinId + ""; + + XmlElement node = (XmlElement) addin.SelectSingleNode ("ExtensionNodeType[@id='" + nodeId + "']"); + if (node == null) + return "Extension point not found: " + nodeId + ""; + + StringBuilder sb = new StringBuilder (""); + sb.Append ("

").Append (node.GetAttribute ("name")).Append ("

"); + XmlElement desc = (XmlElement) node.SelectSingleNode ("Description"); + if (desc != null) + sb.Append (desc.InnerText); + + sb.Append ("

Attributes:

"); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + sb.Append (""); + + foreach (XmlElement at in node.SelectNodes ("Attributes/Attribute")) { + sb.Append (""); + sb.AppendFormat ("", at.GetAttribute ("name")); + sb.AppendFormat ("", at.GetAttribute ("type")); + if (at.GetAttribute ("required") == "True") + sb.Append (""); + else + sb.Append (""); + if (at.GetAttribute ("localizable") == "True") + sb.Append (""); + else + sb.Append (""); + string sdesc = ""; + desc = (XmlElement) at.SelectSingleNode ("Description"); + if (desc != null) + sdesc = desc.InnerText; + + sb.AppendFormat ("", sdesc); + sb.Append (""); + } + sb.Append ("
NameTypeRequiredLocalizableDescription
idSystem.StringIdentifier of the node.
{0}{0}YesYes{0}
"); + + XmlNodeList children = node.SelectNodes ("ChildNodes/ExtensionNode"); + if (children.Count > 0) { + sb.Append ("

Child Nodes:

"); + sb.Append (""); + + foreach (XmlElement en in children) { + string nid = en.GetAttribute ("id"); + string nname = en.GetAttribute ("name"); + string sdesc = ""; + desc = (XmlElement) en.SelectSingleNode ("Description"); + if (desc != null) + sdesc = desc.InnerText; + + sb.AppendFormat ("", fileId, addinId, nid, nname, sdesc); + } + sb.Append ("
{3}{4}
"); + } + + sb.Append (""); + return sb.ToString (); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecma2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecma2Html.cs new file mode 100644 index 00000000000..ed329e35154 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecma2Html.cs @@ -0,0 +1,307 @@ +using System; +using System.IO; +using System.Text; +using System.Linq; +using System.Xml; +using System.Xml.Xsl; +using System.Xml.XPath; +using System.Collections.Generic; + +using Mono.Documentation; +using BF = System.Reflection.BindingFlags; + +namespace MonkeyDoc.Generators.Html +{ + public class Ecma2Html : IHtmlExporter + { + static string css_ecma; + static string js; + static XslCompiledTransform ecma_transform; + readonly ExtensionObject ExtObject = new ExtensionObject (); + + public Ecma2Html () + { + } + + public string CssCode { + get { + if (css_ecma != null) + return css_ecma; + var assembly = typeof(Ecma2Html).Assembly; + Stream str_css = assembly.GetManifestResourceStream ("mono-ecma.css"); + css_ecma = (new StreamReader (str_css)).ReadToEnd(); + return css_ecma; + } + } + + public string JsCode { + get { + if (js != null) + return js; + var assembly = typeof(Ecma2Html).Assembly; + Stream str_js = assembly.GetManifestResourceStream ("helper.js"); + js = (new StreamReader (str_js)).ReadToEnd(); + return js; + } + } + + public string Htmlize (XmlReader ecma_xml, Dictionary extraArgs) + { + var args = new XsltArgumentList (); + args.AddExtensionObject("monodoc:///extensions", ExtObject); + foreach (var kvp in extraArgs) + args.AddParam (kvp.Key, string.Empty, kvp.Value); + + return Htmlize(ecma_xml, args); + } + + public string Htmlize (XmlReader ecma_xml, XsltArgumentList args) + { + EnsureTransform (); + + var output = new StringBuilder (); + ecma_transform.Transform (ecma_xml, + args, + XmlWriter.Create (output, ecma_transform.OutputSettings), + CreateDocumentResolver ()); + return output.ToString (); + } + + protected virtual XmlResolver CreateDocumentResolver () + { + // results in using XmlUrlResolver + return null; + } + + public string Export (Stream stream, Dictionary extraArgs) + { + return Htmlize (XmlReader.Create (stream), extraArgs); + } + + public string Export (string input, Dictionary extraArgs) + { + return Htmlize (XmlReader.Create (new StringReader (input)), extraArgs); + } + + static void EnsureTransform () + { + if (ecma_transform == null) { + ecma_transform = new XslCompiledTransform (); + var assembly = System.Reflection.Assembly.GetCallingAssembly (); + + Stream stream = assembly.GetManifestResourceStream ("mono-ecma-css.xsl"); + XmlReader xml_reader = new XmlTextReader (stream); + XmlResolver r = new ManifestResourceResolver ("."); + ecma_transform.Load (xml_reader, XsltSettings.TrustedXslt, r); + } + } + + public class ExtensionObject + { + bool quiet = true; + + public string Colorize(string code, string lang) + { + return Mono.Utilities.Colorizer.Colorize(code,lang); + } + + // Used by stylesheet to nicely reformat the tags. + public string MakeNiceSignature(string sig, string contexttype) + { + if (sig.Length < 3) + return sig; + if (sig[1] != ':') + return sig; + + char s = sig[0]; + sig = sig.Substring(2); + + switch (s) { + case 'N': return sig; + case 'T': return ShortTypeName (sig, contexttype); + + case 'C': case 'M': case 'P': case 'F': case 'E': + string type, mem, arg; + + // Get arguments + int paren; + if (s == 'C' || s == 'M') + paren = sig.IndexOf("("); + else if (s == 'P') + paren = sig.IndexOf("["); + else + paren = 0; + + if (paren > 0 && paren < sig.Length-1) { + string[] args = sig.Substring(paren+1, sig.Length-paren-2).Split(','); + for (int i = 0; i < args.Length; i++) + args[i] = ShortTypeName(args[i], contexttype); + arg = "(" + String.Join(", ", args) + ")"; + sig = sig.Substring(0, paren); + } else { + arg = string.Empty; + } + + // Get type and member names + int dot = sig.LastIndexOf("."); + if (s == 'C' || dot <= 0 || dot == sig.Length-1) { + mem = string.Empty; + type = sig; + } else { + type = sig.Substring(0, dot); + mem = sig.Substring(dot); + } + + type = ShortTypeName(type, contexttype); + + return type + mem + arg; + + default: + return sig; + } + } + + static string ShortTypeName(string name, string contexttype) + { + int dot = contexttype.LastIndexOf("."); + if (dot < 0) return name; + string contextns = contexttype.Substring(0, dot+1); + + if (name == contexttype) + return name.Substring(dot+1); + + if (name.StartsWith(contextns)) + return name.Substring(contextns.Length); + + return name.Replace("+", "."); + } + + string MonoImpInfo(string assemblyname, string typename, string membername, string arglist, bool strlong) + { + if (quiet) + return string.Empty; + + var a = new List (); + if (!string.IsNullOrEmpty (arglist)) a.Add (arglist); + return MonoImpInfo(assemblyname, typename, membername, a, strlong); + } + + string MonoImpInfo(string assemblyname, string typename, string membername, XPathNodeIterator itr, bool strlong) + { + if (quiet) + return string.Empty; + + var rgs = itr.Cast ().Select (nav => nav.Value).ToList (); + + return MonoImpInfo (assemblyname, typename, membername, rgs, strlong); + } + + string MonoImpInfo(string assemblyname, string typename, string membername, List arglist, bool strlong) + { + try { + System.Reflection.Assembly assembly = null; + + try { + assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname); + } catch (Exception) { + // nothing. + } + + if (assembly == null) { + /*if (strlong) return "The assembly " + assemblyname + " is not available to MonoDoc."; + else return string.Empty;*/ + return string.Empty; // silently ignore + } + + Type t = assembly.GetType(typename, false); + if (t == null) { + if (strlong) + return typename + " has not been implemented."; + else + return "Not implemented."; + } + + // The following code is flakey and fails to find existing members + return string.Empty; + } catch (Exception) { + return string.Empty; + } + } + + string MonoImpInfo(System.Reflection.MemberInfo mi, string itemtype, bool strlong) + { + if (quiet) + return string.Empty; + + string s = string.Empty; + + object[] atts = mi.GetCustomAttributes(true); + int todoctr = 0; + foreach (object att in atts) if (att.GetType().Name == "MonoTODOAttribute") todoctr++; + + if (todoctr > 0) { + if (strlong) + s = "This " + itemtype + " is marked as being unfinished.
\n"; + else + s = "Unfinished."; + } + + return s; + } + + public string MonoImpInfo(string assemblyname, string typename, bool strlong) + { + if (quiet) + return string.Empty; + + try { + if (assemblyname == string.Empty) + return string.Empty; + + var assembly = System.Reflection.Assembly.LoadWithPartialName(assemblyname); + if (assembly == null) + return string.Empty; + + Type t = assembly.GetType(typename, false); + if (t == null) { + if (strlong) + return typename + " has not been implemented."; + else + return "Not implemented."; + } + + string s = MonoImpInfo(t, "type", strlong); + + if (strlong) { + var mis = t.GetMembers (BF.Static | BF.Instance | BF.Public | BF.NonPublic); + + // Scan members for MonoTODO attributes + int mctr = 0; + foreach (var mi in mis) { + string mii = MonoImpInfo(mi, null, false); + if (mii != string.Empty) mctr++; + } + if (mctr > 0) { + s += "This type has " + mctr + " members that are marked as unfinished.
"; + } + } + + return s; + + } catch (Exception) { + return string.Empty; + } + } + + public bool MonoEditing () + { + return false; + } + + public bool IsToBeAdded(string text) + { + return text.StartsWith ("To be added"); + } + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecmaspec2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecmaspec2Html.cs new file mode 100644 index 00000000000..95f4064083f --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Ecmaspec2Html.cs @@ -0,0 +1,66 @@ +using System; +using System.IO; +using System.Xml; +using System.Xml.Xsl; +using System.Xml.XPath; +using System.Collections.Generic; + +namespace MonkeyDoc.Generators.Html +{ + public class Ecmaspec2Html : IHtmlExporter + { + static string css_ecmaspec; + static XslTransform ecma_transform; + static XsltArgumentList args = new XsltArgumentList(); + + public string CssCode { + get { + if (css_ecmaspec != null) + return css_ecmaspec; + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetCallingAssembly (); + Stream str_css = assembly.GetManifestResourceStream ("ecmaspec.css"); + css_ecmaspec = (new StreamReader (str_css)).ReadToEnd (); + return css_ecmaspec; + } + } + + class ExtObj + { + public string Colorize (string code, string lang) + { + return Mono.Utilities.Colorizer.Colorize (code, lang); + } + } + + public string Export (Stream stream, Dictionary extraArgs) + { + return Htmlize (new XPathDocument (stream)); + } + + public string Export (string input, Dictionary extraArgs) + { + return Htmlize (new XPathDocument (new StringReader (input))); + } + + static string Htmlize (XPathDocument ecma_xml) + { + if (ecma_transform == null){ + ecma_transform = new XslTransform (); + System.Reflection.Assembly assembly = System.Reflection.Assembly.GetCallingAssembly (); + Stream stream; + stream = assembly.GetManifestResourceStream ("ecmaspec-html-css.xsl"); + + XmlReader xml_reader = new XmlTextReader (stream); + ecma_transform.Load (xml_reader, null, null); + args.AddExtensionObject ("monodoc:///extensions", new ExtObj ()); + } + + if (ecma_xml == null) return ""; + + StringWriter output = new StringWriter (); + ecma_transform.Transform (ecma_xml, args, output, null); + + return output.ToString (); + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Error2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Error2Html.cs new file mode 100644 index 00000000000..167d1f54248 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Error2Html.cs @@ -0,0 +1,110 @@ +using System; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.XPath; +using System.Collections.Generic; + +namespace MonkeyDoc.Generators.Html +{ + public class Error2Html : IHtmlExporter + { + public string Export (string input, Dictionary extraArgs) + { + return Htmlize (new XPathDocument (new StringReader (input))); + } + + public string Export (Stream input, Dictionary extraArgs) + { + return Htmlize (new XPathDocument (input)); + } + + public string CssCode { + get { + return @" + #error_ref { + background: #debcb0; + border: 2px solid #782609; + } + div.summary { + font-size: 110%; + font-weight: bolder; + } + div.details { + font-size: 110%; + font-weight: bolder; + } + div.code_example { + background: #f5f5dd; + border: 1px solid black; + padding-left: 1em; + padding-bottom: 1em; + margin-top: 1em; + white-space: pre; + margin-bottom: 1em; + } + div.code_ex_title { + position: relative; + top: -1em; + left: 30%; + background: #cdcd82; + border: 1px solid black; + color: black; + font-size: 65%; + text-transform: uppercase; + width: 40%; + padding: 0.3em; + text-align: center; + }"; + } + } + + public string Htmlize (IXPathNavigable doc) + { + var navigator = doc.CreateNavigator (); + var errorName = navigator.SelectSingleNode ("//ErrorDocumentation/ErrorName"); + var details = navigator.SelectSingleNode ("//ErrorDocumentation/Details"); + + StringWriter sw = new StringWriter (); + XmlWriter w = new XmlTextWriter (sw); + + WriteElementWithClass (w, "div", "header"); + w.WriteAttributeString ("id", "error_ref"); + WriteElementWithClass (w, "div", "subtitle", "Compiler Error Reference"); + WriteElementWithClass (w, "div", "title", "Error " + (errorName == null ? string.Empty : errorName.Value)); + w.WriteEndElement (); + + if (details != null) { + WriteElementWithClass (w, "div", "summary", "Summary"); + + var summary = details.SelectSingleNode ("/Summary"); + w.WriteValue (summary == null ? string.Empty : summary.Value); + + WriteElementWithClass (w, "div", "details", "Details"); + var de = details.SelectSingleNode ("/Details"); + w.WriteValue (de == null ? string.Empty : de.Value); + } + + foreach (XPathNavigator xmp in navigator.Select ("//ErrorDocumentation/Examples/string")) { + WriteElementWithClass (w, "div", "code_example"); + WriteElementWithClass (w, "div", "code_ex_title", "Example"); + w.WriteRaw (Mono.Utilities.Colorizer.Colorize (xmp.Value, "c#"));; + w.WriteEndElement (); + } + + w.Close (); + + return sw.ToString (); + } + + void WriteElementWithClass (XmlWriter w, string element, string cls, string content = null) + { + w.WriteStartElement (element); + w.WriteAttributeString ("class", cls); + if (!string.IsNullOrEmpty (content)) { + w.WriteValue (content); + w.WriteEndElement (); + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Idem.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Idem.cs new file mode 100644 index 00000000000..0a58b213afc --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Idem.cs @@ -0,0 +1,34 @@ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +using MonkeyDoc; +using MonkeyDoc.Generators; + +namespace MonkeyDoc.Generators.Html +{ + // Input is expected to be already HTML so just return it + public class Idem : IHtmlExporter + { + public string CssCode { + get { + return string.Empty; + } + } + + public string Export (Stream input, Dictionary extraArgs) + { + if (input == null) + return null; + return new StreamReader (input).ReadToEnd (); + } + + public string Export (string input, Dictionary extraArgs) + { + if (string.IsNullOrEmpty (input)) + return null; + return input; + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Man2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Man2Html.cs new file mode 100644 index 00000000000..68ed5ed9280 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Man2Html.cs @@ -0,0 +1,316 @@ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +using MonkeyDoc; +using MonkeyDoc.Generators; + +namespace MonkeyDoc.Generators.Html +{ + public class Man2Html : IHtmlExporter + { + public string CssCode { + get { + return string.Empty; + } + } + + public string Export (Stream input, Dictionary extraArgs) + { + if (input == null) + return null; + return GetTextFromReader (new StreamReader (input)); + } + + public string Export (string input, Dictionary extraArgs) + { + if (string.IsNullOrEmpty (input)) + return null; + return GetTextFromReader (new StringReader (input)); + } + + public static string GetTextFromReader (TextReader file) + { + string line; + StateInfo s = new StateInfo (); + + while ((line = file.ReadLine ()) != null) + ProcessLine (line, s); + + return s.output.ToString (); + } + + enum ListState { + None, + Start, + Title, + } + + class StateInfo { + public ListState ls; + public Stack tags = new Stack (); + public StringBuilder output = new StringBuilder (); + } + + static void ProcessLine (string line, StateInfo s) + { + string[] parts = SplitLine (line); + switch (parts [0]) { + case ".\\\"": // comments + case ".de": // define macro + case ".if": // if + case ".ne": // ??? + case "..": // end macro + // ignore + break; + case ".I": + s.output.Append (""); + Translate (parts, 1, s.output); + s.output.Append (""); + break; + case ".B": + s.output.Append (""); + Translate (parts, 1, s.output); + s.output.Append (""); + break; + case ".br": + Translate (parts, 1, s.output); + s.output.Append ("
"); + break; + case ".nf": + Expect (s, "

"); + s.output.Append ("
\n");
+				s.tags.Push ("
"); + break; + case ".fi": + Expect (s, ""); + break; + case ".PP": + Expect (s, "

", "", ""); + goto case ".Sp"; + case ".Sp": + Expect (s, "

"); + s.output.Append ("

"); + Translate (parts, 1, s.output); + s.tags.Push ("

"); + break; + case ".RS": + Expect (s, "

"); + s.output.Append ("
"); + s.tags.Push ("
"); + break; + case ".RE": + ClearUntil (s, ""); + break; + case ".SH": + ClearAll (s); + s.output.Append ("

"); + Translate (parts, 1, s.output); + s.output.Append ("

") + .Append ("
"); + s.tags.Push ("
"); + break; + case ".SS": + s.output.Append ("

"); + Translate (parts, 1, s.output); + s.output.Append ("

"); + break; + case ".TH": { + ClearAll (s); + string name = "", extra = ""; + if (parts.Length >= 4 && parts [2].Trim ().Length == 0) { + name = parts [1] + "(" + parts [3] + ")"; + if (parts.Length > 4) { + int start = 4; + if (parts [start].Trim ().Length == 0) + ++start; + extra = string.Join ("", parts, start, parts.Length-start); + } + } + else + name = string.Join ("", parts, 1, parts.Length-1); + s.output.Append ("" + + "\n" + + "
Manual Pages

"); + Translate (name, s.output); + s.output.Append ("

"); + Translate (extra, s.output); + s.output.Append ("
"); + break; + } + case ".TP": + Expect (s, "

"); + if (s.tags.Count > 0 && s.tags.Peek ().ToString () != "") { + s.output.Append ("
"); + s.tags.Push ("
"); + } + else + Expect (s, ""); + s.output.Append ("
"); + s.tags.Push ("
"); + s.ls = ListState.Start; + break; + default: + Translate (line, s.output); + break; + } + if (s.ls == ListState.Start) + s.ls = ListState.Title; + else if (s.ls == ListState.Title) { + Expect (s, ""); + s.output.Append ("
"); + s.tags.Push ("
"); + s.ls = ListState.None; + } + s.output.Append ("\n"); + } + + static string[] SplitLine (string line) + { + if (line.Length > 1 && line [0] != '.') + return new string[]{null, line}; + + int i; + for (i = 0; i < line.Length; ++i) { + if (char.IsWhiteSpace (line, i)) + break; + } + + if (i == line.Length) + return new string[]{line}; + + var pieces = new List (); + pieces.Add (line.Substring (0, i)); + bool inQuotes = false; + bool prevWs = true; + ++i; + int start = i; + for ( ; i < line.Length; ++i) { + char c = line [i]; + if (inQuotes) { + if (c == '"') { + Add (pieces, line, start, i); + start = i+1; + inQuotes = false; + } + } + else { + if (prevWs && c == '"') { + Add (pieces, line, start, i); + start = i+1; + inQuotes = true; + } + else if (char.IsWhiteSpace (c)) { + if (!prevWs) { + Add (pieces, line, start, i); + start = i; + } + prevWs = true; + } + else { + if (prevWs) { + Add (pieces, line, start, i); + start = i; + } + prevWs = false; + } + } + } + if (start > 0 && start != line.Length) + pieces.Add (line.Substring (start, line.Length-start)); + return pieces.ToArray (); + } + + static void Add (List pieces, string line, int start, int end) + { + if (start == end) + return; + pieces.Add (line.Substring (start, end-start)); + } + + static void Expect (StateInfo s, params string[] expected) + { + string e; + while (s.tags.Count > 0 && + Array.IndexOf (expected, (e = s.tags.Peek ().ToString ())) >= 0) { + s.output.Append (s.tags.Pop ().ToString ()); + } + } + + static void ClearUntil (StateInfo s, string required) + { + string e; + while (s.tags.Count > 0 && + (e = s.tags.Peek ().ToString ()) != required) { + s.output.Append (s.tags.Pop ().ToString ()); + } + if (e == required) + s.output.Append (s.tags.Pop ().ToString ()); + } + + static void ClearAll (StateInfo s) + { + while (s.tags.Count > 0) + s.output.Append (s.tags.Pop ().ToString ()); + } + + static void Translate (string[] lines, int startIndex, StringBuilder output) + { + if (lines.Length <= startIndex) + return; + do { + Translate (lines [startIndex++], output); + if (startIndex == lines.Length) + break; + } while (startIndex < lines.Length); + } + + static void Translate (string line, StringBuilder output) + { + string span = null; + int start = output.Length; + for (int i = 0; i < line.Length; ++i) { + switch (line [i]) { + case '\\': { + if ((i+2) < line.Length && line [i+1] == 'f') { + if (line [i+2] == 'I') { + output.Append (""); + span = ""; + } + else if (line [i+2] == 'B') { + output.Append (""); + span = ""; + } + else if (line [i+2] == 'R' || line [i+2] == 'P') { + output.Append (span); + } + else + goto default; + i += 2; + } + else if ((i+1) < line.Length) { + output.Append (line [i+1]); + ++i; + } + else + goto default; + break; + } + case '<': + output.Append ("<"); + break; + case '>': + output.Append (">"); + break; + case '&': + output.Append ("&"); + break; + default: + output.Append (line [i]); + break; + } + } + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/MonoBook2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/MonoBook2Html.cs new file mode 100644 index 00000000000..89a531c2168 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/MonoBook2Html.cs @@ -0,0 +1,87 @@ +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Collections.Generic; + +using MonkeyDoc; +using MonkeyDoc.Generators; + +namespace MonkeyDoc.Generators.Html +{ + // Input is expected to be already HTML so just return it + public class MonoBook2Html : IHtmlExporter + { + public string CssCode { + get { + return @" h3 { + font-size: 18px; + padding-bottom: 4pt; + border-bottom: 2px solid #dddddd; + } + + .api { + border: 1px solid; + padding: 10pt; + margin: 10pt; + } + + .api-entry { + border-bottom: none; + font-size: 18px; + } + + .prototype { + border: 1px solid; + background-color: #f2f2f2; + padding: 5pt; + margin-top: 5pt; + margin-bottom: 5pt; + } + + .header { + border: 1px solid !important; + padding: 0 0 5pt 5pt !important; + margin: 10pt !important; + white-space: pre !important; + font-family: monospace !important; + font-weight: normal !important; + font-size: 1em !important; + } + + .code { + border: 1px solid; + padding: 0 0 5pt 5pt; + margin: 10pt; + white-space: pre; + font-family: monospace; + } +"; + } + } + + public string Export (Stream input, Dictionary extraArgs) + { + if (input == null) + return null; + return FromXmlReader (XmlReader.Create (input)); + } + + public string Export (string input, Dictionary extraArgs) + { + if (string.IsNullOrEmpty (input)) + return null; + return FromXmlReader (XmlReader.Create (new StringReader (input))); + } + + public string FromXmlReader (XmlReader reader) + { + if (!reader.ReadToDescendant ("head")) + return null; + if (!reader.ReadToNextSibling ("body")) + return null; + + return reader.ReadInnerXml (); + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/generators/html/Toc2Html.cs b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Toc2Html.cs new file mode 100644 index 00000000000..eef17c234f0 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/generators/html/Toc2Html.cs @@ -0,0 +1,44 @@ +using System; +using System.IO; +using System.Xml; +using System.Xml.Xsl; +using System.Xml.XPath; +using System.Reflection; +using System.Collections.Generic; + +namespace MonkeyDoc.Generators.Html +{ + public class Toc2Html : IHtmlExporter + { + XslTransform transform; + + public Toc2Html () + { + transform = new XslTransform (); + var assembly = Assembly.GetCallingAssembly (); + var stream = assembly.GetManifestResourceStream ("toc-html.xsl"); + XmlReader xml_reader = new XmlTextReader (stream); + transform.Load (xml_reader, null, null); + } + + public string Export (Stream input, Dictionary extraArgs) + { + var output = new StringWriter (); + transform.Transform (new XPathDocument (input), null, output, null); + return output.ToString (); + } + + public string Export (string input, Dictionary extraArgs) + { + var output = new StringWriter (); + transform.Transform (new XPathDocument (new StringReader (input)), null, output, null); + return output.ToString (); + } + + public string CssCode { + get { + return string.Empty; + } + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/index.cs b/mcs/tools/monkeydoc/Monkeydoc/index.cs new file mode 100644 index 00000000000..62e4e31cbb5 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/index.cs @@ -0,0 +1,360 @@ +// +// index.cs: Handling of the index files +// +// Author: +// Miguel de Icaza (miguel@xamarin.com) +// +// (C) 2003 Ximian, Inc. +// Copyright 2003-2011 Novell Inc +// Copyright 2011 Xamarin Inc. +// +// Possible file format optimizations: +// * Do not use 4 bytes for each index entry, use 3 bytes +// * Find a way of compressing strings, there are plenty of duplicates +// Find common roots, and use an encoding that uses a root to compress data. +// "System", "System.Data", "System.Data class" +// 0: PLAIN: "System" +// 1: PLAIN: " class" +// 2: LINK0 PLAIN ".DATA" +// 3: LINK0 LINK1 +// +// Maybe split everything at spaces and dots, and encode that: +// string-1-idx "System." +// string-1-idx "Data" +// 2-items [ string-1-idx string-2-idx] +// +// Other variations are possible; Like Archive "System", "System." when we +// see "System.Data". +// +// + +using System; +using System.IO; +using System.Text; +using System.Collections; + +namespace MonkeyDoc +{ + + public class Topic { + public readonly string Caption; + public readonly string SortKey; + public readonly string Url; + + public Topic (string caption, string sort_key, string url) + { + Caption = caption; + SortKey = sort_key; + Url = url; + } + } + + public class IndexEntry { + public int Position; + public object topics; + public int Count; + + public void Add (Topic t) + { + Count++; + if (topics == null) + topics = t; + else { + if (!(topics is ArrayList)){ + Topic temp = (Topic) topics; + + topics = new ArrayList (); + ((ArrayList)topics).Add (temp); + } + ((ArrayList)topics).Add (t); + } + } + + public Topic this [int idx] { + get { + if (topics is Topic){ + if (idx == 0) + return (Topic) topics; + else + throw new Exception ("Out of range index"); + } else { + return (Topic) (((ArrayList)topics) [idx]); + } + } + } + + // + // Constructor from a stream + // + public IndexEntry (FileStream fs, BinaryReader reader, int position) + { + Count = reader.ReadInt32 (); + int caption_offset = reader.ReadInt32 (); + string caption; + + if (Count == 1){ + int url_offset = reader.ReadInt32 (); + fs.Position = caption_offset; + caption = reader.ReadString (); + fs.Position = url_offset; + string url = reader.ReadString (); + topics = new Topic (caption, "", url); + } else { + ArrayList l = new ArrayList (Count); + topics = l; + int [] offsets = new int [Count]; + for (int i = 0; i < Count; i++){ + offsets [i] = reader.ReadInt32 (); + } + fs.Position = caption_offset; + caption = reader.ReadString (); + for (int i = 0; i < Count; i++){ + fs.Position = offsets [i]; + string url = reader.ReadString (); + l.Add (new Topic (caption, "", url)); + } + } + } + + // Topic ReadTopic (FileStream fs, BinaryReader reader, ref string caption) + // { + // int caption_offset = -1; + // if (caption == null) + // caption_offset = reader.ReadInt32 (); + // int url_offset = reader.ReadInt32 (); + // + // if (caption == null){ + // fs.Position = caption_offset; + // caption = reader.ReadString (); + // } + // fs.Position = url_offset; + // string url = reader.ReadString (); + // + // return new Topic (caption, "", url); + // } + + // + // Regular constructor + + public IndexEntry () + { + } + + public void WriteTopics (IndexMaker maker, Stream stream, BinaryWriter writer) + { + // + // Convention: entries with the same SortKey should have the same Caption + // + Position = (int) stream.Position; + writer.Write (Count); + + if (topics is ArrayList){ + bool first = true; + foreach (Topic t in (ArrayList) topics){ + if (first){ + writer.Write (maker.GetCode (t.Caption)); + first = false; + } + writer.Write (maker.GetCode (t.Url)); + } + } else { + Topic t = (Topic) topics; + + writer.Write (maker.GetCode (t.Caption)); + writer.Write (maker.GetCode (t.Url)); + } + } + } + + public class IndexMaker { + Hashtable entries = new Hashtable (); + Hashtable all_strings = new Hashtable (); + + void add_string (string s) + { + if (all_strings.Contains (s)) + return; + all_strings [s] = 0; + } + + public void AddTopic (Topic topic) + { + IndexEntry entry = (IndexEntry) entries [topic.SortKey]; + if (entry == null){ + entry = new IndexEntry (); + entries [topic.SortKey] = entry; + } + + add_string (topic.SortKey); + add_string (topic.Caption); + add_string (topic.Url); + entry.Add (topic); + } + + public void Add (string caption, string sort_key, string url) + { + Topic t = new Topic (caption, sort_key, url); + AddTopic (t); + } + + void SaveStringTable (Stream stream, BinaryWriter writer) + { + ICollection k = all_strings.Keys; + string [] ks = new string [k.Count]; + k.CopyTo (ks, 0); + + foreach (string s in ks){ + int pos = (int) stream.Position; + writer.Write (s); + all_strings [s] = pos; + } + } + + public int GetCode (string s) + { + return (int) all_strings [s]; + } + + int index_position; + + void SaveTopics (Stream stream, BinaryWriter writer) + { + // + // Convention: entries with the same SortKey should have the same Caption + // + foreach (IndexEntry e in entries.Values) + e.WriteTopics (this, stream, writer); + } + + void SaveIndexEntries (Stream stream, BinaryWriter writer) + { + index_position = (int) stream.Position; + writer.Write (entries.Count); + ICollection keys = entries.Keys; + string [] keys_name = new string [keys.Count]; + keys.CopyTo (keys_name, 0); + Array.Sort (keys_name, new NameSort ()); + + foreach (string s in keys_name){ + IndexEntry e = (IndexEntry) entries [s]; + writer.Write (e.Position); + } + } + + class NameSort : IComparer { + public int Compare (object a, object b) + { + string sa = (string) a; + string sb = (string) b; + + return String.Compare (sa, sb, StringComparison.OrdinalIgnoreCase); + } + } + + public void Save (string filename) + { + Encoding utf8 = new UTF8Encoding (false, true); + + using (FileStream fs = File.OpenWrite (filename)){ + BinaryWriter writer = + new BinaryWriter (fs, utf8); + writer.Write (new byte [] { (byte) 'M', + (byte) 'o', (byte) 'i', + (byte) 'x'}); + + // Leave room for pointer + fs.Position = 8; + + SaveStringTable (fs, writer); + SaveTopics (fs, writer); + + // index_position is set here + + SaveIndexEntries (fs, writer); + + fs.Position = 4; + writer.Write (index_position); + } + } + } + + public interface IListModel { + int Rows {get; } + string GetValue (int row); + string GetDescription (int row); + } + + public class IndexReader : IListModel { + Encoding utf8 = new UTF8Encoding (false, true); + FileStream fs; + BinaryReader reader; + + // The offset of the table of entries + int table_offset; + int entries; + + static public IndexReader Load (string filename) + { + if (!File.Exists (filename)) + return null; + + try { + return new IndexReader (filename); + } catch { + return null; + } + } + + IndexReader (string filename) + { + fs = File.OpenRead (filename); + reader = new BinaryReader (fs, utf8); + + if (fs.ReadByte () != 'M' || + fs.ReadByte () != 'o' || + fs.ReadByte () != 'i' || + fs.ReadByte () != 'x'){ + throw new Exception ("Corrupt index"); + } + + // Seek to index_entries + fs.Position = reader.ReadInt32 (); + + entries = reader.ReadInt32 (); + + table_offset = (int) fs.Position; + } + + public int Rows { + get { + return entries; + } + } + + public string GetValue (int row) + { + fs.Position = row * 4 + table_offset; + fs.Position = reader.ReadInt32 () + 4; + int code = reader.ReadInt32 (); + fs.Position = code; + string caption = reader.ReadString (); + + return caption; + } + + public string GetDescription (int row) + { + return GetValue (row); + } + + public IndexEntry GetIndexEntry (int row) + { + fs.Position = row * 4 + table_offset; + int entry_offset = reader.ReadInt32 (); + fs.Position = entry_offset; + + return new IndexEntry (fs, reader, entry_offset); + } + } +} + diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/addins-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/addins-provider.cs new file mode 100644 index 00000000000..3768717ac19 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/addins-provider.cs @@ -0,0 +1,136 @@ +// addins-provider.cs +// +// A provider to display Mono.Addins extension models +// +// Author: +// Lluis Sanchez Gual +// +// Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.Linq; +using System.Diagnostics; +using System.Text; +using System.IO; +using System.Xml; +using System.Collections.Generic; + +namespace MonkeyDoc.Providers +{ + public class AddinsProvider : Provider + { + string file; + + public AddinsProvider (string xmlModelFile) + { + file = xmlModelFile; + + if (!File.Exists (file)) + throw new FileNotFoundException (String.Format ("The file `{0}' does not exist", file)); + } + + public override void PopulateTree (Tree tree) + { + string fileId = Path.GetFileNameWithoutExtension (file); + using (var f = File.OpenRead (file)) + tree.HelpSource.Storage.Store (fileId, f); + + XmlDocument doc = new XmlDocument (); + doc.Load (file); + + foreach (XmlElement addin in doc.SelectNodes ("Addins/Addin")) { + + string addinId = addin.GetAttribute ("fullId"); + Node newNode = tree.RootNode.CreateNode (addin.GetAttribute ("name"), "addin:" + fileId + "#" + addinId); + + foreach (XmlElement node in addin.SelectNodes ("ExtensionPoint")) { + string target = "extension-point:" + fileId + "#" + addinId + "#" + node.GetAttribute ("path"); + Node newExt = newNode.CreateNode (node.GetAttribute ("name"), target); + + foreach (XmlElement en in node.SelectNodes ("ExtensionNode")) { + string nid = en.GetAttribute ("id"); + string nname = en.GetAttribute ("name"); + newExt.CreateNode (nname, "extension-node:" + fileId + "#" + addinId + "#" + nid); + } + } + } + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + } + } + + public class AddinsHelpSource : HelpSource + { + public AddinsHelpSource (string base_file, bool create) : base (base_file, create) + { + } + + internal protected const string AddinPrefix = "addin:"; + internal protected const string ExtensionPrefix = "extension-point:"; + internal protected const string ExtensionNodePrefix = "extension-node:"; + + public override bool CanHandleUrl (string url) + { + return url.StartsWith (AddinPrefix, StringComparison.OrdinalIgnoreCase) + || url.StartsWith (ExtensionPrefix, StringComparison.OrdinalIgnoreCase) + || url.StartsWith (ExtensionNodePrefix, StringComparison.OrdinalIgnoreCase); + } + + protected override string UriPrefix { + get { + return AddinPrefix; + } + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraArgs) + { + extraArgs = new Dictionary (); + var idParts = id.Split ('#'); + extraArgs["FileID"] = idParts[0]; + extraArgs["AddinID"] = idParts[1]; + extraArgs["NodeID"] = idParts[2]; + + return DocumentType.AddinXml; + } + + public override Node MatchNode (string url) + { + var prefix = new[] { AddinPrefix, ExtensionPrefix, ExtensionNodePrefix }.First (p => url.StartsWith (p, StringComparison.OrdinalIgnoreCase)); + return base.MatchNode (prefix != null ? url.Substring (prefix.Length) : url); + } + + public override Stream GetHelpStream (string id) + { + var idParts = id.Split ('#'); + return base.GetHelpStream (idParts[0]); + } + + public override Stream GetCachedHelpStream (string id) + { + var idParts = id.Split ('#'); + return base.GetHelpStream (idParts[0]); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/ecma-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/ecma-provider.cs new file mode 100644 index 00000000000..8d0ca2d3e0e --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/ecma-provider.cs @@ -0,0 +1,763 @@ +// +// The ecmaspec provider is for ECMA specifications +// +// Authors: +// John Luke (jluke@cfl.rr.com) +// Ben Maurer (bmaurer@users.sourceforge.net) +// +// Use like this: +// mono assembler.exe --ecmaspec DIRECTORY --out name +// + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Linq; +using System.Collections.Generic; + +using Lucene.Net.Index; +using Lucene.Net.Documents; + +using Monkeydoc.Ecma; +using Mono.Utilities; + +namespace MonkeyDoc.Providers +{ + public enum EcmaNodeType { + Invalid, + Namespace, + Type, + Member, + Meta, // A node that's here to serve as a header for other node + } + + public class EcmaProvider : Provider + { + HashSet directories = new HashSet (); + + public EcmaProvider () + { + } + + public EcmaProvider (string baseDir) + { + AddDirectory (baseDir); + } + + public void AddDirectory (string directory) + { + if (string.IsNullOrEmpty (directory)) + throw new ArgumentNullException ("directory"); + + directories.Add (directory); + } + + public override void PopulateTree (Tree tree) + { + var root = tree.RootNode; + var storage = tree.HelpSource.Storage; + int resID = 0; + var nsSummaries = new Dictionary (); + + foreach (var asm in directories) { + var indexFilePath = Path.Combine (asm, "index.xml"); + if (!File.Exists (indexFilePath)) { + Console.Error.WriteLine ("Warning: couldn't process directory `{0}' as it has no index.xml file", asm); + continue; + } + using (var reader = XmlReader.Create (File.OpenRead (indexFilePath))) { + reader.ReadToFollowing ("Types"); + var types = XElement.Load (reader.ReadSubtree ()); + + foreach (var ns in types.Elements ("Namespace")) { + var nsName = (string)ns.Attribute ("Name"); + nsName = !string.IsNullOrEmpty (nsName) ? nsName : "global"; + var nsNode = root.GetOrCreateNode (nsName, "N:" + nsName); + + XElement nsElements; + if (!nsSummaries.TryGetValue (nsName, out nsElements)) + nsSummaries[nsName] = nsElements = new XElement ("elements", + new XElement ("summary"), + new XElement ("remarks")); + + foreach (var type in ns.Elements ("Type")) { + // Add the XML file corresponding to the type to our storage + var id = resID++; + var typeFilePath = Path.Combine (asm, nsName, Path.ChangeExtension (type.Attribute ("Name").Value, ".xml")); + if (!File.Exists (typeFilePath)) { + Console.Error.WriteLine ("Warning: couldn't process type file `{0}' as it doesn't exist", typeFilePath); + continue; + } + using (var file = File.OpenRead (typeFilePath)) + storage.Store (id.ToString (), file); + nsElements.Add (ExtractClassSummary (typeFilePath)); + + var typeCaption = ((string)(type.Attribute ("DisplayName") ?? type.Attribute ("Name"))).Replace ('+', '.'); + var url = "ecma:" + id + '#' + typeCaption + '/'; + var typeNode = nsNode.CreateNode (typeCaption, url); + + // Add meta "Members" node + typeNode.CreateNode ("Members", "*"); + var typeDocument = XDocument.Load (typeFilePath); + var membersNode = typeDocument.Root.Element ("Members"); + if (membersNode == null || !membersNode.Elements ().Any ()) + continue; + var members = membersNode + .Elements ("Member") + .ToLookup (m => m.Attribute ("MemberName").Value.StartsWith ("op_") ? "Operator" : m.Element ("MemberType").Value); + + foreach (var memberType in members) { + // We pluralize the member type to get the caption and take the first letter as URL + var node = typeNode.CreateNode (PluralizeMemberType (memberType.Key), memberType.Key[0].ToString ()); + var memberIndex = 0; + + var isCtors = memberType.Key[0] == 'C'; + + // We do not escape much member name here + foreach (var memberGroup in memberType.GroupBy (m => MakeMemberCaption (m, isCtors))) { + if (memberGroup.Count () > 1) { + // Generate overload + var overloadCaption = MakeMemberCaption (memberGroup.First (), false); + var overloadNode = node.CreateNode (overloadCaption, overloadCaption); + foreach (var member in memberGroup) + overloadNode.CreateNode (MakeMemberCaption (member, true), (memberIndex++).ToString ()); + overloadNode.Sort (); + } else { + // We treat constructor differently by showing their argument list in all cases + node.CreateNode (MakeMemberCaption (memberGroup.First (), isCtors), (memberIndex++).ToString ()); + } + } + node.Sort (); + } + } + + nsNode.Sort (); + } + root.Sort (); + } + } + + foreach (var summary in nsSummaries) + storage.Store ("xml.summary." + summary.Key, summary.Value.ToString ()); + + var masterSummary = new XElement ("elements", + directories + .SelectMany (d => Directory.EnumerateFiles (d, "ns-*.xml")) + .Select (ExtractNamespaceSummary)); + storage.Store ("mastersummary.xml", masterSummary.ToString ()); + } + + string PluralizeMemberType (string memberType) + { + switch (memberType) { + case "Property": + return "Properties"; + default: + return memberType + "s"; + } + } + + string MakeMemberCaption (XElement member, bool withArguments) + { + var caption = (string)member.Attribute ("MemberName"); + // Use type name instead of .ctor for cosmetic sake + if (caption == ".ctor") { + caption = (string)member.Ancestors ("Type").First ().Attribute ("Name"); + // If this is an inner type ctor, strip the parent type reference + var plusIndex = caption.LastIndexOf ('+'); + if (plusIndex != -1) + caption = caption.Substring (plusIndex + 1); + } + if (caption.StartsWith ("op_")) { + string sig; + caption = MakeOperatorSignature (member, out sig); + caption = withArguments ? sig : caption; + return caption; + } + if (withArguments) { + var args = member.Element ("Parameters"); + caption += '('; + if (args != null && args.Elements ("Parameter").Any ()) { + caption += args.Elements ("Parameter") + .Select (p => (string)p.Attribute ("Type")) + .Aggregate ((p1, p2) => p1 + "," + p2); + } + caption += ')'; + } + + return caption; + } + + XElement ExtractClassSummary (string typeFilePath) + { + using (var reader = XmlReader.Create (typeFilePath)) { + reader.ReadToFollowing ("Type"); + var name = reader.GetAttribute ("Name"); + var fullName = reader.GetAttribute ("FullName"); + reader.ReadToFollowing ("AssemblyName"); + var assemblyName = reader.ReadElementString (); + reader.ReadToFollowing ("summary"); + var summary = reader.ReadInnerXml (); + reader.ReadToFollowing ("remarks"); + var remarks = reader.ReadInnerXml (); + + return new XElement ("class", + new XAttribute ("name", name ?? string.Empty), + new XAttribute ("fullname", fullName ?? string.Empty), + new XAttribute ("assembly", assemblyName ?? string.Empty), + new XElement ("summary", new XCData (summary)), + new XElement ("remarks", new XCData (remarks))); + } + } + + XElement ExtractNamespaceSummary (string nsFile) + { + using (var reader = XmlReader.Create (nsFile)) { + reader.ReadToFollowing ("Namespace"); + var name = reader.GetAttribute ("Name"); + reader.ReadToFollowing ("summary"); + var summary = reader.ReadInnerXml (); + reader.ReadToFollowing ("remarks"); + var remarks = reader.ReadInnerXml (); + + return new XElement ("namespace", + new XAttribute ("ns", name ?? string.Empty), + new XElement ("summary", new XCData (summary)), + new XElement ("remarks", new XCData (remarks))); + } + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + AddImages (hs); + AddExtensionMethods (hs); + } + + void AddEcmaXml (HelpSource hs) + { + var xmls = directories + .SelectMany (Directory.EnumerateDirectories) // Assemblies + .SelectMany (Directory.EnumerateDirectories) // Namespaces + .SelectMany (Directory.EnumerateFiles) + .Where (f => f.EndsWith (".xml")); // Type XML files + + int resID = 0; + foreach (var xml in xmls) + using (var file = File.OpenRead (xml)) + hs.Storage.Store ((resID++).ToString (), file); + } + + void AddImages (HelpSource hs) + { + var imgs = directories + .SelectMany (Directory.EnumerateDirectories) + .Select (d => Path.Combine (d, "_images")) + .Where (Directory.Exists) + .SelectMany (Directory.EnumerateFiles); + + foreach (var img in imgs) + using (var file = File.OpenRead (img)) + hs.Storage.Store (Path.GetFileName (img), file); + } + + void AddExtensionMethods (HelpSource hs) + { + var extensionMethods = directories + .SelectMany (Directory.EnumerateDirectories) + .Select (d => Path.Combine (d, "index.xml")) + .Where (File.Exists) + .Select (f => { + using (var file = File.OpenRead (f)) { + var reader = XmlReader.Create (file); + reader.ReadToFollowing ("ExtensionMethods"); + return reader.ReadInnerXml (); + } + }) + .DefaultIfEmpty (string.Empty); + + hs.Storage.Store ("ExtensionMethods.xml", + "" + extensionMethods.Aggregate (string.Concat) + ""); + } + + IEnumerable GetEcmaXmls () + { + return directories + .SelectMany (Directory.EnumerateDirectories) // Assemblies + .SelectMany (Directory.EnumerateDirectories) // Namespaces + .SelectMany (Directory.EnumerateFiles) + .Where (f => f.EndsWith (".xml")); // Type XML files + } + + string MakeOperatorSignature (XElement member, out string memberSignature) + { + string name = (string)member.Attribute ("MemberName"); + var nicename = name.Substring(3); + memberSignature = null; + + switch (name) { + // unary operators: no overloading possible [ECMA-335 §10.3.1] + case "op_UnaryPlus": // static R operator+ (T) + case "op_UnaryNegation": // static R operator- (T) + case "op_LogicalNot": // static R operator! (T) + case "op_OnesComplement": // static R operator~ (T) + case "op_Increment": // static R operator++ (T) + case "op_Decrement": // static R operator-- (T) + case "op_True": // static bool operator true (T) + case "op_False": // static bool operator false (T) + case "op_AddressOf": // static R operator& (T) + case "op_PointerDereference": // static R operator* (T) + memberSignature = nicename; + break; + // conversion operators: overloading based on parameter and return type [ECMA-335 §10.3.3] + case "op_Implicit": // static implicit operator R (T) + case "op_Explicit": // static explicit operator R (T) + nicename = name.EndsWith ("Implicit") ? "ImplicitConversion" : "ExplicitConversion"; + string arg = (string)member.Element ("Parameters").Element ("Parameter").Attribute ("Type"); + string ret = (string)member.Element ("ReturnValue").Element ("ReturnType"); + memberSignature = arg + " to " + ret; + break; + // binary operators: overloading is possible [ECMA-335 §10.3.2] + default: + memberSignature = + nicename + "(" + + string.Join (",", member.Element ("Parameters").Elements ("Parameter").Select (p => (string)p.Attribute ("Type"))) + + ")"; + break; + } + + return nicename; + } + } + + public class EcmaHelpSource : HelpSource + { + const string EcmaPrefix = "ecma:"; + EcmaUrlParser parser = new EcmaUrlParser (); + LRUCache cache = new LRUCache (4); + + public EcmaHelpSource (string base_file, bool create) : base (base_file, create) + { + } + + protected override string UriPrefix { + get { + return EcmaPrefix; + } + } + + public override bool CanHandleUrl (string url) + { + if (url.Length > 2 && url[1] == ':') { + switch (url[0]) { + case 'T': + case 'M': + case 'C': + case 'P': + case 'E': + case 'F': + case 'N': + case 'O': + return true; + } + } + return base.CanHandleUrl (url); + } + + // Clean the extra paramers in the id + public override Stream GetHelpStream (string id) + { + var idParts = id.Split ('?'); + return base.GetHelpStream (idParts[0]); + } + + public override Stream GetCachedHelpStream (string id) + { + var idParts = id.Split ('?'); + return base.GetCachedHelpStream (idParts[0]); + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraParams) + { + extraParams = null; + int interMark = id.LastIndexOf ('?'); + if (interMark != -1) + extraParams = id.Substring (interMark) + .Split ('&') + .Select (nvp => { + var eqIdx = nvp.IndexOf ('='); + return new { Key = nvp.Substring (0, eqIdx < 0 ? nvp.Length : eqIdx), Value = nvp.Substring (eqIdx + 1) }; + }) + .ToDictionary (kvp => kvp.Key, kvp => kvp.Value ); + return DocumentType.EcmaXml; + } + + public override string GetPublicUrl (Node node) + { + string url = string.Empty; + var type = GetNodeType (node); + //Console.WriteLine ("GetPublicUrl {0} : {1} [{2}]", node.Element, node.Caption, type.ToString ()); + switch (type) { + case EcmaNodeType.Namespace: + return node.Element; // A namespace node has already a well formated internal url + case EcmaNodeType.Type: + return MakeTypeNodeUrl (node); + case EcmaNodeType.Meta: + return MakeTypeNodeUrl (GetNodeTypeParent (node)) + GenerateMetaSuffix (node); + case EcmaNodeType.Member: + var typeChar = GetNodeMemberTypeChar (node); + var parentNode = GetNodeTypeParent (node); + var typeNode = MakeTypeNodeUrl (parentNode).Substring (2); + return typeChar + ":" + typeNode + MakeMemberNodeUrl (typeChar, node); + default: + return null; + } + } + + string MakeTypeNodeUrl (Node node) + { + // A Type node has a Element property of the form: 'ecma:{number}#{typename}/' + var hashIndex = node.Element.IndexOf ('#'); + var typeName = node.Element.Substring (hashIndex + 1, node.Element.Length - hashIndex - 2); + return "T:" + node.Parent.Caption + '.' + typeName.Replace ('.', '+'); + } + + string MakeMemberNodeUrl (char typeChar, Node node) + { + // We clean inner type ctor name which may contain the outer type name + var caption = node.Caption; + + // Sanitize constructor caption of inner types + if (typeChar == 'C') { + int lastDot = -1; + for (int i = 0; i < caption.Length && caption[i] != '('; i++) + lastDot = caption[i] == '.' ? i : lastDot; + return lastDot == -1 ? '.' + caption : caption.Substring (lastDot); + } + + /* We handle type conversion operator by checking if the name contains " to " + * (as in 'foo to bar') and we generate a corresponding conversion signature + */ + if (typeChar == 'O' && caption.IndexOf (" to ") != -1) { + var parts = caption.Split (' '); + return "." + node.Parent.Caption + "(" + parts[0] + ", " + parts[2] + ")"; + } + + /* The goal here is to treat method which are explicit interface definition + * such as 'void IDisposable.Dispose ()' for which the caption is a dot + * expression thus colliding with the ecma parser. + * If the first non-alpha character in the caption is a dot then we have an + * explicit member implementation (we assume the interface has namespace) + */ + var firstNonAlpha = caption.FirstOrDefault (c => !char.IsLetterOrDigit (c)); + if (firstNonAlpha == '.') + return "$" + caption; + + return "." + caption; + } + + EcmaNodeType GetNodeType (Node node) + { + // We guess the node type by checking the depth level it's at in the tree + int level = GetNodeLevel (node); + switch (level) { + case 0: + return EcmaNodeType.Namespace; + case 1: + return EcmaNodeType.Type; + case 2: + return EcmaNodeType.Meta; + case 3: // Here it's either a member or, in case of overload, a meta + return node.IsLeaf ? EcmaNodeType.Member : EcmaNodeType.Meta; + case 4: // At this level, everything is necessarily a member + return EcmaNodeType.Member; + default: + return EcmaNodeType.Invalid; + } + } + + int GetNodeLevel (Node node) + { + int i = 0; + for (; !node.Element.StartsWith ("root:/", StringComparison.OrdinalIgnoreCase); i++) { + //Console.WriteLine ("\tLevel {0} : {1} {2}", i, node.Element, node.Caption); + node = node.Parent; + } + return i - 1; + } + + char GetNodeMemberTypeChar (Node node) + { + int level = GetNodeLevel (node); + // We try to reach the member group node depending on node nested level + switch (level) { + case 2: + return node.Element[0]; + case 3: + return node.Parent.Element[0]; + case 4: + return node.Parent.Parent.Element[0]; + default: + throw new ArgumentException ("node", "Couldn't determine member type of node `" + node.Caption + "'"); + } + } + + Node GetNodeTypeParent (Node node) + { + // Type nodes are always at level 2 so we just need to get there + while (node != null && node.Parent != null && !node.Parent.Parent.Element.StartsWith ("root:/", StringComparison.OrdinalIgnoreCase)) + node = node.Parent; + return node; + } + + string GenerateMetaSuffix (Node node) + { + string suffix = string.Empty; + // A meta node has always a type element to begin with + while (GetNodeType (node) != EcmaNodeType.Type) { + suffix = '/' + node.Element + suffix; + node = node.Parent; + } + return suffix; + } + + public override string GetInternalIdForUrl (string url, out Node node) + { + var id = string.Empty; + node = null; + + if (!url.StartsWith (EcmaPrefix, StringComparison.OrdinalIgnoreCase)) { + node = MatchNode (url); + if (node == null) + return null; + id = node.GetInternalUrl (); + } + + if (id.StartsWith (UriPrefix, StringComparison.OrdinalIgnoreCase)) + id = id.Substring (UriPrefix.Length); + else if (id.StartsWith ("N:", StringComparison.OrdinalIgnoreCase)) + id = "xml.summary." + id.Substring ("N:".Length); + + var hashIndex = id.IndexOf ('#'); + var hash = string.Empty; + if (hashIndex != -1) { + hash = id.Substring (hashIndex + 1); + id = id.Substring (0, hashIndex); + } + + return id + GetArgs (hash, node); + } + + public override Node MatchNode (string url) + { + Node node = null; + if ((node = cache.Get (url)) == null) { + node = InternalMatchNode (url); + if (node != null) + cache.Put (url, node); + } + return node; + } + + public Node InternalMatchNode (string url) + { + Node result = null; + EcmaDesc desc; + if (!parser.TryParse (url, out desc)) + return null; + + // Namespace search + Node currentNode = Tree.RootNode; + Node searchNode = new Node () { Caption = desc.Namespace }; + int index = currentNode.Nodes.BinarySearch (searchNode, EcmaGenericNodeComparer.Instance); + if (index >= 0) + result = currentNode.Nodes[index]; + if (desc.DescKind == EcmaDesc.Kind.Namespace || index < 0) + return result; + + // Type search + currentNode = result; + result = null; + searchNode.Caption = desc.ToCompleteTypeName (); + index = currentNode.Nodes.BinarySearch (searchNode, EcmaTypeNodeComparer.Instance); + if (index >= 0) + result = currentNode.Nodes[index]; + if ((desc.DescKind == EcmaDesc.Kind.Type && !desc.IsEtc) || index < 0) + return result; + + // Member selection + currentNode = result; + result = null; + var caption = desc.IsEtc ? EtcKindToCaption (desc.Etc) : MemberKindToCaption (desc.DescKind); + currentNode = FindNodeForCaption (currentNode.Nodes, caption); + if (currentNode == null + || (desc.IsEtc && desc.DescKind == EcmaDesc.Kind.Type && string.IsNullOrEmpty (desc.EtcFilter))) + return currentNode; + + // Member search + result = null; + var format = desc.DescKind == EcmaDesc.Kind.Constructor ? EcmaDesc.Format.WithArgs : EcmaDesc.Format.WithoutArgs; + searchNode.Caption = desc.ToCompleteMemberName (format); + index = currentNode.Nodes.BinarySearch (searchNode, EcmaGenericNodeComparer.Instance); + if (index < 0) + return null; + result = currentNode.Nodes[index]; + if (result.Nodes.Count == 0 || desc.IsEtc) + return result; + + // Overloads search + currentNode = result; + searchNode.Caption = desc.ToCompleteMemberName (EcmaDesc.Format.WithArgs); + index = currentNode.Nodes.BinarySearch (searchNode, EcmaGenericNodeComparer.Instance); + if (index < 0) + return result; + result = result.Nodes[index]; + + return result; + } + + // This comparer returns the answer straight from caption comparison + class EcmaGenericNodeComparer : IComparer + { + public static readonly EcmaGenericNodeComparer Instance = new EcmaGenericNodeComparer (); + + public int Compare (Node n1, Node n2) + { + return string.Compare (n1.Caption, n2.Caption, StringComparison.Ordinal); + } + } + + // This comparer take into account the space in the caption + class EcmaTypeNodeComparer : IComparer + { + public static readonly EcmaTypeNodeComparer Instance = new EcmaTypeNodeComparer (); + + public int Compare (Node n1, Node n2) + { + int length1 = CaptionLength (n1.Caption); + int length2 = CaptionLength (n2.Caption); + + return string.Compare (n1.Caption, 0, n2.Caption, 0, Math.Max (length1, length2), StringComparison.Ordinal); + } + + int CaptionLength (string caption) + { + var length = caption.LastIndexOf (' '); + return length == -1 ? caption.Length : length; + } + } + + string EtcKindToCaption (char etc) + { + switch (etc) { + case 'M': + return "Methods"; + case 'P': + return "Properties"; + case 'C': + return "Constructors"; + case 'F': + return "Fields"; + case 'E': + return "Events"; + case 'O': + return "Operators"; + case '*': + return "Members"; + default: + return null; + } + } + + string MemberKindToCaption (EcmaDesc.Kind kind) + { + switch (kind) { + case EcmaDesc.Kind.Method: + return "Methods"; + case EcmaDesc.Kind.Property: + return "Properties"; + case EcmaDesc.Kind.Constructor: + return "Constructors"; + case EcmaDesc.Kind.Field: + return "Fields"; + case EcmaDesc.Kind.Event: + return "Events"; + case EcmaDesc.Kind.Operator: + return "Operators"; + default: + return null; + } + } + + Node FindNodeForCaption (List nodes, string caption) + { + foreach (var node in nodes) + if (node.Caption.Equals (caption, StringComparison.OrdinalIgnoreCase)) + return node; + return null; + } + + string GetArgs (string hash, Node node) + { + var args = new Dictionary (); + + args["source-id"] = SourceID.ToString (); + + if (node != null) { + var nodeType = GetNodeType (node); + switch (nodeType) { + case EcmaNodeType.Namespace: + args["show"] = "namespace"; + args["namespace"] = node.Element.Substring ("N:".Length); + break; + case EcmaNodeType.Type: + args["show"] = "typeoverview"; + break; + case EcmaNodeType.Member: + case EcmaNodeType.Meta: + switch (GetNodeMemberTypeChar (node)){ + case 'C': + args["membertype"] = "Constructor"; + break; + case 'M': + args["membertype"] = "Method"; + break; + case 'P': + args["membertype"] = "Property"; + break; + case 'F': + args["membertype"] = "Field"; + break; + case 'E': + args["membertype"] = "Event"; + break; + case 'O': + args["membertype"] = "Operator"; + break; + case 'X': + args["membertype"] = "ExtensionMethod"; + break; + case '*': + args["membertype"] = "All"; + break; + } + + if (nodeType == EcmaNodeType.Meta) { + args["show"] = "members"; + args["index"] = "all"; + } else { + args["show"] = "member"; + args["index"] = node.Element; + } + break; + } + } + + if (!string.IsNullOrEmpty (hash)) + args["hash"] = hash; + + return "?" + string.Join ("&", args.Select (kvp => kvp.Key == kvp.Value ? kvp.Key : kvp.Key + '=' + kvp.Value)); + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/ecmaspec-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/ecmaspec-provider.cs new file mode 100644 index 00000000000..bbe71ebd242 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/ecmaspec-provider.cs @@ -0,0 +1,194 @@ +// +// The ecmaspec provider is for ECMA specifications +// +// Authors: +// John Luke (jluke@cfl.rr.com) +// Ben Maurer (bmaurer@users.sourceforge.net) +// +// Use like this: +// mono assembler.exe --ecmaspec DIRECTORY --out name +// + +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Xml.XPath; +using System.Xml.Xsl; +using System.Xml; +using System.Collections.Generic; +using Lucene.Net.Index; +using Lucene.Net.Documents; + +namespace MonkeyDoc.Providers +{ + public class EcmaSpecProvider : Provider + { + string basedir; + + public EcmaSpecProvider (string base_directory) + { + basedir = base_directory; + if (!Directory.Exists (basedir)) + throw new DirectoryNotFoundException (String.Format ("The directory `{0}' does not exist", basedir)); + } + + public override void PopulateTree (Tree tree) + { + XPathNavigator n = new XPathDocument (Path.Combine (basedir, "toc.xml")).CreateNavigator (); + n.MoveToRoot (); + n.MoveToFirstChild (); + PopulateNode (n.SelectChildren ("node", ""), tree.RootNode); + } + + void PopulateNode (XPathNodeIterator nodes, Node treeNode) + { + foreach (XPathNavigator n in nodes) { + string secNumber = n.GetAttribute ("number", ""); + string secName = n.GetAttribute ("name", ""); + + var storage = treeNode.Tree.HelpSource.Storage; + using (var file = File.OpenRead (Path.Combine (basedir, secNumber + ".xml"))) + storage.Store (secNumber, file); + + Node thisNode = treeNode.GetOrCreateNode (secNumber + ": " + secName, "ecmaspec:" + secNumber); + + if (n.HasChildren) + PopulateNode (n.SelectChildren ("node", ""), thisNode); + } + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + } + } + + public class EcmaSpecHelpSource : HelpSource + { + const string EcmaspecPrefix = "ecmaspec:"; + const string TocPart = "%toc"; // What is returned as TocXml + const string SpecPart = "%spec"; // What is returned as Ecmaspec + + public EcmaSpecHelpSource (string base_file, bool create) : base (base_file, create) + { + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraParams) + { + extraParams = null; + return id.EndsWith (TocPart) ? DocumentType.TocXml : DocumentType.EcmaSpecXml; + } + + public override bool IsGeneratedContent (string id) + { + return id == "root:" || id.EndsWith (TocPart); + } + + public override bool IsMultiPart (string id, out IEnumerable parts) + { + if (id == "root:" || id.EndsWith (TocPart) || id.EndsWith (SpecPart)) { + parts = null; + return false; + } + parts = MakeMultiPart (id); + return true; + } + + IEnumerable MakeMultiPart (string baseId) + { + yield return baseId + SpecPart; + yield return baseId + TocPart; + } + + public override string GetText (string id) + { + Node n = id == "root:" ? Tree.RootNode : MatchNode (EcmaspecPrefix + id.Substring (0, id.Length - TocPart.Length)); + if (n == null) + throw new ArgumentException ("id", string.Format ("{0} -> {1}", id, EcmaspecPrefix + id.Substring (0, id.Length - TocPart.Length))); + return TreeDumper.ExportToTocXml (n, "C# Language Specification", "In this section:"); + } + + public override Stream GetHelpStream (string id) + { + return id.EndsWith (SpecPart) ? base.GetHelpStream (id.Substring (0, id.IndexOf (SpecPart))) : base.GetHelpStream (id); + } + + public override void PopulateSearchableIndex (IndexWriter writer) + { + foreach (Node n in Tree.RootNode.Nodes) + AddDocuments (writer, n); + } + + protected override string UriPrefix { + get { + return EcmaspecPrefix; + } + } + + void AddDocuments (IndexWriter writer, Node node) + { + string url = node.PublicUrl; + Stream file_stream = GetHelpStream (url.Substring (9)); + if (file_stream == null) //Error + return; + XmlDocument xdoc = new XmlDocument (); + xdoc.Load (new XmlTextReader (file_stream)); + + //Obtain the title + XmlNode nelem = xdoc.DocumentElement; + string title = nelem.Attributes["number"].Value + ": " + nelem.Attributes["title"].Value; + + //Obtain the text + StringBuilder s = new StringBuilder (); + GetTextNode (nelem, s); + string text = s.ToString (); + + //Obtain the examples + StringBuilder s2 = new StringBuilder (); + GetExamples (nelem, s2); + string examples = s2.ToString (); + + //Write to the Lucene Index all the parts + SearchableDocument doc = new SearchableDocument (); + doc.title = title; + doc.hottext = title.Substring (title.IndexOf (':')); + doc.url = url; + doc.text = text; + doc.examples = examples; + writer.AddDocument (doc.LuceneDoc); + + if (node.IsLeaf) + return; + + foreach (Node n in node.Nodes) + AddDocuments (writer, n); + } + + void GetTextNode (XmlNode n, StringBuilder s) + { + //dont include c# code + if (n.Name == "code_example") + return; + //include all text from nodes + if (n.NodeType == XmlNodeType.Text) + s.Append (n.Value); + + //recursively explore all nodes + if (n.HasChildNodes) + foreach (XmlNode n_child in n.ChildNodes) + GetTextNode (n_child, s); + } + + void GetExamples (XmlNode n, StringBuilder s) + { + if (n.Name == "code_example") { + if (n.FirstChild.Name == "#cdata-section") + s.Append (n.FirstChild.Value); + } else { + if (n.HasChildNodes) + foreach (XmlNode n_child in n.ChildNodes) + GetExamples (n_child, s); + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/error-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/error-provider.cs new file mode 100644 index 00000000000..0c1597ecdd6 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/error-provider.cs @@ -0,0 +1,201 @@ +// +// error-provider.cs +// +// Author: +// Ben Maurer (bmaurer@users.sourceforge.net) +// +// (C) 2003 Ben Maurer +// Copyright 2003-2011 Novell +// Copyright 2011 Xamarin Inc +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.Linq; +using Lucene.Net.Index; +using Lucene.Net.Documents; + +namespace MonkeyDoc.Providers +{ + public class ErrorProviderConfig + { + public string FilesPath; + public string Match; + public int ErrorNumSubstringStart; + public int ErrorNumSubstringLength; + public string FriendlyFormatString; + + public override string ToString () + { + var sb = new StringBuilder (); + var w = new StringWriter (sb); + + w.WriteLine ("FilesPath: {0}", FilesPath); + w.WriteLine ("Match: {0}", Match); + w.WriteLine ("Error Number Substring: {0} Length:{1}", ErrorNumSubstringStart, ErrorNumSubstringLength); + w.WriteLine ("FriendlyFormatString: {0}", FriendlyFormatString); + + return w.ToString (); + } + + public Dictionary Compile (HelpSource hs) + { + string[] files = Directory.GetFiles (FilesPath, Match); + var ret = new Dictionary (); + + foreach (string s in files) { + ErrorDocumentation d; + int errorNum = 0; + + try { + errorNum = int.Parse (Path.GetFileName (s).Substring (ErrorNumSubstringStart, ErrorNumSubstringLength)); + } catch { + Console.WriteLine ("Ignoring file {0}", s); + } + + string errorName = String.Format (FriendlyFormatString, errorNum); + + if (!ret.TryGetValue (errorName, out d)) + ret[errorName] = d = new ErrorDocumentation (errorName); + + if (d.Details == null) { + string xmlFile = Path.ChangeExtension (s, "xml"); + if (File.Exists (xmlFile)) { + XmlSerializer cfgRdr = new XmlSerializer (typeof (ErrorDetails)); + d.Details = (ErrorDetails)cfgRdr.Deserialize (new XmlTextReader (xmlFile)); + } + } + // Encoding is same as used in MCS, so we will be able to do all those files + using (StreamReader reader = new StreamReader (s, Encoding.GetEncoding (28591))) { + d.Examples.Add (reader.ReadToEnd ()); + } + } + + return ret; + } + } + + public class ErrorDocumentation + { + public string ErrorName; + public ErrorDetails Details; + public List Examples = new List (); + + public ErrorDocumentation () {} + public ErrorDocumentation (string ErrorName) + { + this.ErrorName = ErrorName; + } + } + + public class ErrorDetails + { + public XmlNode Summary; + public XmlNode Details; + } + + public class ErrorProvider : Provider + { + ErrorProviderConfig config; + + public ErrorProvider (string configFile) + { + config = ReadConfig (configFile); + } + + public static ErrorProviderConfig ReadConfig (string file) + { + XmlSerializer cfgRdr = new XmlSerializer (typeof (ErrorProviderConfig)); + ErrorProviderConfig ret = (ErrorProviderConfig)cfgRdr.Deserialize (new XmlTextReader (file)); + // handle path rel to the config file + ret.FilesPath = Path.Combine (Path.GetDirectoryName (file), ret.FilesPath); + return ret; + } + + public override void PopulateTree (Tree tree) + { + // everything is done in CloseTree so we can pack + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + var entries = config.Compile (hs); + MemoryStream ms = new MemoryStream (); + XmlSerializer writer = new XmlSerializer (typeof (ErrorDocumentation)); + + foreach (var de in entries) { + ErrorDocumentation d = de.Value; + string s = de.Key; + + tree.RootNode.GetOrCreateNode (s, "error:" + s); + + writer.Serialize (ms, d); + ms.Position = 0; + hs.Storage.Store (s, ms); + ms.SetLength (0); + } + + tree.RootNode.Sort (); + } + } + + public class ErrorHelpSource : HelpSource + { + public ErrorHelpSource (string base_file, bool create) : base (base_file, create) + { + } + + public override string GetText (string id) + { + return TreeDumper.ExportToTocXml (Tree.RootNode, "Compiler Error Reference", "In this section:"); + } + + protected override string UriPrefix { + get { + return "error:"; + } + } + + public override bool IsGeneratedContent (string id) + { + return id == "root:"; + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraParams) + { + extraParams = null; + return id == "root:" ? DocumentType.TocXml : DocumentType.ErrorXml; + } + + public override string GetInternalIdForUrl (string url, out Node node) + { + var result = base.GetInternalIdForUrl (url, out node); + return result.ToLower (); + } + + public override void PopulateIndex (IndexMaker index_maker) + { + foreach (Node n in Tree.RootNode.Nodes) + index_maker.Add (n.Caption, n.Caption, n.Element); + } + + public override void PopulateSearchableIndex (IndexWriter writer) + { + foreach (Node n in Tree.RootNode.Nodes) { + XmlSerializer reader = new XmlSerializer (typeof (ErrorDocumentation)); + ErrorDocumentation d = (ErrorDocumentation)reader.Deserialize (GetHelpStream (n.Element.Substring (6))); + SearchableDocument doc = new SearchableDocument (); + doc.title = d.ErrorName; + doc.url = n.Element; + doc.text = d.Details != null ? d.Details.ToString () : string.Empty; + doc.examples = d.Examples.Cast ().Aggregate ((e1, e2) => e1 + Environment.NewLine + e2); + doc.hottext = d.ErrorName; + writer.AddDocument (doc.LuceneDoc); + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/man-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/man-provider.cs new file mode 100755 index 00000000000..32b9c9347eb --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/man-provider.cs @@ -0,0 +1,106 @@ +// +// A provider to display man pages +// +// Authors: +// Johannes Roith +// Jonathan Pryor +// +// (C) 2008 Novell, Inc. + +using System; +using System.IO; +using System.Text; +using System.Xml; +using System.Linq; +using System.Collections.Generic; + +namespace MonkeyDoc.Providers +{ + public class ManProvider : Provider + { + string[] tocFiles; + + public ManProvider (string[] handbookTocFiles) + { + tocFiles = handbookTocFiles; + + // huh... + if (!File.Exists (tocFiles[0])) + throw new FileNotFoundException (String.Format ("The table of contents, `{0}' does not exist", tocFiles[0])); + } + + public override void PopulateTree (Tree tree) + { + foreach(string TocFile in tocFiles) { + XmlDocument doc = new XmlDocument(); + doc.Load (TocFile); + + XmlNodeList nodeList = doc.GetElementsByTagName("manpage"); + Node nodeToAddChildrenTo = tree.RootNode; + var storage = nodeToAddChildrenTo.Tree.HelpSource.Storage; + + foreach (XmlNode node in nodeList) { + + XmlAttribute name = node.Attributes["name"]; + XmlAttribute page = node.Attributes["page"]; + + if (name == null || page == null) continue; + + if (!File.Exists (page.Value)) + continue; + + string target = "man:" + name.Value; + nodeToAddChildrenTo.CreateNode (name.Value, target); + + if (File.Exists (page.Value)) + storage.Store (name.Value, File.OpenRead (page.Value)); + } + } + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + } + } + + public class ManHelpSource : HelpSource + { + const string ManPrefix = "man:"; + Dictionary nodesMap; + + public ManHelpSource (string base_file, bool create) : base (base_file, create) + { + nodesMap = Tree.RootNode.Nodes.ToDictionary (n => n.Element); + } + + // Since man always has a flat tree and rather small amount of item + // we store them in a dictionary + public override Node MatchNode (string url) + { + Node result; + return nodesMap.TryGetValue (url, out result) ? result : null; + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraParams) + { + extraParams = null; + return id == "root:" ? DocumentType.TocXml : DocumentType.Man; + } + + public override bool IsGeneratedContent (string id) + { + return id == "root:"; + } + + public override string GetText (string url) + { + return TreeDumper.ExportToTocXml (Tree.RootNode, "Mono Documentation Library", "Available man pages:"); + } + + protected override string UriPrefix { + get { + return ManPrefix; + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/simple-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/simple-provider.cs new file mode 100644 index 00000000000..e567dc19660 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/simple-provider.cs @@ -0,0 +1,153 @@ +// +// The simple provider is an example provider +// +// Author: +// Miguel de Icaza (miguel@ximian.com) +// +// Use like this: +// mono assembler.exe --simple DIRECTORY --out name +// +// Then create a .source file in your sources directory, and copy +// name.tree and name.zip to the sources directory. +// +// To view the tree generated, use: +// mono dump.exe name.tree +// +namespace Monodoc { +using System; +using System.IO; +using System.Text; + +// +// The simple provider generates the information source +// +public class SimpleProvider : Provider { + string basedir; + + public SimpleProvider (string base_directory) + { + basedir = base_directory; + if (!Directory.Exists (basedir)) + throw new FileNotFoundException (String.Format ("The directory `{0}' does not exist", basedir)); + } + + public override void PopulateTree (Tree tree) + { + Node top = tree.LookupNode ("Directory at: " + basedir, "simple:"); + + foreach (string dir in Directory.GetDirectories (basedir)){ + string url = Path.GetFileName (dir); + Node n = top.LookupNode ("Dir: " + url, url); + PopulateDir (n, dir); + } + } + +#pragma warning disable 219 + void PopulateDir (Node me, string dir) + { + Console.WriteLine ("Adding: " + dir); + foreach (string child_dir in Directory.GetDirectories (dir)){ + string url = Path.GetFileName (child_dir); + Node n = me.LookupNode ("Dir: " + url, "simple-directory:" + url); + PopulateDir (me, child_dir); + } + + foreach (string file in Directory.GetFiles (dir)){ + Console.WriteLine (" File: " + file); + string file_code = me.tree.HelpSource.PackFile (file); + + // + // The url element encoded for the file is: + // originalfilename#CODE + // + // The code is assigned to us after the file has been packaged + // We use the original-filename later to render html or text files + // + Node n = me.LookupNode (Path.GetFileName (file), file + "#" + file_code); + + } + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + } +} + +// +// The HelpSource is used during the rendering phase. +// + +public class SimpleHelpSource : HelpSource { + Encoding enc; + + public SimpleHelpSource (string base_file, bool create) : base (base_file, create) + { + enc = new UTF8Encoding (false, false); + } + + public override string GetText (string url, out Node match_node) + { + match_node = null; + + string c = GetCachedText (url); + if (c != null) + return c; + + if (url.StartsWith ("simple:") || url.StartsWith ("simple-directory:")) + return GetTextFromUrl (url); + + return null; + } + + string GetTextFromUrl (string url) + { + // Remove "simple:" prefix + url = url.Substring (7); + + if (url.StartsWith ("simple-directory:")) + return String.Format ("This is a directory entry point: {0} ", + url.Substring (17)); + + // Otherwise the last element of the url is the file code we got. + int pound = url.LastIndexOf ("#"); + string code; + if (pound == -1) + code = url; + else + code = url.Substring (pound+1); + + + Stream s = GetHelpStream (code); + if (s == null) + return String.Format ("No stream for this node: {0} ", url); + + // + // Now, get the file type + // + int slash = url.LastIndexOf ("/"); + string fname = url.Substring (slash + 1, pound - slash - 1).ToLower (); + + if (fname.EndsWith (".html") || fname.EndsWith (".htm")){ + TextReader r = new StreamReader (s, enc); + return r.ReadToEnd (); + } + + if (fname.EndsWith (".png") || fname.EndsWith (".jpg") || + fname.EndsWith (".jpeg") || fname.EndsWith (".gif")){ + return "Image file, have not implemented rendering this yet"; + } + + // Convert text to HTML + StringBuilder result = new StringBuilder (""); + TextReader reader = new StreamReader (s, enc); + string line; + + while ((line = reader.ReadLine ()) != null){ + result.Append (line); + result.Append ("
"); + } + result.Append (""); + return result.ToString (); + } +} +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/providers/xhtml-provider.cs b/mcs/tools/monkeydoc/Monkeydoc/providers/xhtml-provider.cs new file mode 100644 index 00000000000..ce74b013f2e --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/providers/xhtml-provider.cs @@ -0,0 +1,200 @@ +// +// A provider that uses Windows help file xhtml TOC files and looks for the +// referenced documents to create the help source. +// +// Authors: +// Copyright 2003 Lee Mallabone +// Johannes Roith +// Miguel de Icaza + +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; + +namespace MonkeyDoc.Providers +{ + public class XhtmlProvider : Provider + { + string tocFile; + + public XhtmlProvider (string handbookTocFile) + { + tocFile = handbookTocFile; + if (!File.Exists (tocFile)) + throw new FileNotFoundException (String.Format ("The table of contents, `{0}' does not exist", tocFile)); + } + + public override void PopulateTree (Tree tree) + { + //new SimpleHandbookTOCParser(tree, tocFile); + // TODO: port it + } + + public override void CloseTree (HelpSource hs, Tree tree) + { + } + } + + public class XhtmlHelpSource : HelpSource + { + public XhtmlHelpSource (string base_file, bool create) : base (base_file, create) + { + + } + + const string XhtmlPrefix = "xhtml:"; + + protected override string UriPrefix { + get { + return XhtmlPrefix; + } + } + + public override DocumentType GetDocumentTypeForId (string id, out Dictionary extraArgs) + { + extraArgs = null; + return id == "root:" ? DocumentType.TocXml : DocumentType.MonoBook; + } + + public override bool IsGeneratedContent (string id) + { + return id == "root:"; + } + + public override string GetText (string url) + { + return TreeDumper.ExportToTocXml (Tree.RootNode, "Mono Handbook", string.Empty); + } + + public static string GetAbsoluteLink(string target, string url) + { + + string value = null; + + if (target.StartsWith ("#") || + target.StartsWith ("T:") || + target.StartsWith ("M:") || + target.StartsWith ("P:") || + target.StartsWith ("T:") || + target.StartsWith ("E:") || + target.StartsWith ("F:") || + target.StartsWith ("O:") || + target.StartsWith ("N:") || + target.StartsWith ("api:")) + return null; + + int endp = target.IndexOf(':'); + + if (endp == -1) + endp = 0; + string protocol = target.Substring(0, endp); + switch (protocol) { + case "mailto": + case "http": + case "https": + case "ftp": + case "news": + case "irc": + break; + default: + // handle absolute urls like: /html/en/images/empty.png + if (!target.StartsWith("/")) { + + // url is something like "gnome/bindings/mono.html" + // This will get the path "gnome/bindings" + + int slash = url.LastIndexOf ("/"); + string tmpurl = url; + + if (slash != -1) + tmpurl = url.Substring(0, slash); + + // Count "../" in target and go one level down + // for each in tmpurl, eventually, then remove "../". + + Regex reg1 = new Regex("../"); + MatchCollection matches = reg1.Matches(target); + + for(int i = 1; i < matches.Count; i++) { + slash = tmpurl.LastIndexOf ("/"); + if (slash != -1) + tmpurl = tmpurl.Substring(0, slash); + } + + target = target.Replace("../", ""); + + value = tmpurl + "/" + target; + + } else { + value = target.Substring(1, target.Length - 1); + } + break; + } + return value; + } + + XmlDocument RewriteLinks(XmlDocument docToProcess, string url) + { + XmlNodeList nodeList = docToProcess.GetElementsByTagName("a"); + + foreach(XmlNode node in nodeList) { + + XmlElement element = (XmlElement) node; + + if (element.HasAttribute("href") ){ + + XmlAttribute href = element.GetAttributeNode("href"); + string target = href.Value; + + target = GetAbsoluteLink(target, url); + if (target != null) { + string newtarget = String.Format ("source-id:{0}:xhtml:{1}", SourceID, target); + href.Value = newtarget; + } + } + } + + nodeList = docToProcess.GetElementsByTagName("img"); + + foreach(XmlNode node in nodeList) { + + XmlElement element = (XmlElement) node; + + if (element.HasAttribute("src") ){ + + XmlAttribute href = element.GetAttributeNode("src"); + string target = href.Value; + + target = GetAbsoluteLink(target, url); + if (target != null) { + string newtarget = String.Format ("source-id:{0}:xhtml:{1}", SourceID, target); + href.Value = newtarget; + } + } + } + + return docToProcess; + } + + public override void PopulateIndex (IndexMaker index_maker) + { + PopulateIndexFromNodes (Tree.RootNode); + } + + void PopulateIndexFromNodes (Node start) + { + var nodes = start.Nodes; + + if (nodes == null) + Console.WriteLine ("Leaf: " + start.Caption); + else { + Console.WriteLine ("Root: " + start.Caption); + foreach (Node n in nodes) + PopulateIndexFromNodes (n); + } + } + } +} diff --git a/mcs/tools/monkeydoc/Monkeydoc/storage.cs b/mcs/tools/monkeydoc/Monkeydoc/storage.cs new file mode 100644 index 00000000000..9085ff5e40c --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/storage.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using System.Collections.Generic; + +namespace MonkeyDoc +{ + // Define a storage mechanism for a help source + public interface IDocStorage : IDisposable + { + // Tell if the storage can store successive change to the doc as revision + bool SupportRevision { get; } + IDocRevisionManager RevisionManager { get; } + + // Tell if the storage support modifying an existing data + bool SupportChange { get; } + + /* Store data inside the storage backend + * if SupportChange is false and user try to store something with an existing id + * an exception will be thrown + * if id is null or empty, the storage will try to create an automatic id. In all + * case the id that has been used to store the content is returned by the method + */ + string Store (string id, string text); + string Store (string id, byte[] data); + string Store (string id, Stream stream); + + Stream Retrieve (string id); + + IEnumerable GetAvailableIds (); + } + + public interface IDocRevisionManager + { + Stream RetrieveWithRevision (string id, string revision); + + // This should be ordered by most recent first + IEnumerable AvailableRevisionsForId (string id); + // This can simply be implemented with above property but it can also be + // a revision storage symbolic value like "HEAD" + string LatestRevisionForId (string id); + + // A commit message for instance + string GetRevisionDescription (string revision); + } + + public static class DocRevisionManagerExtensions + { + public static Stream RetrieveLatestRevision (this IDocRevisionManager revManager, string id) + { + return revManager.RetrieveWithRevision (id, revManager.LatestRevisionForId (id)); + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Monkeydoc/storage/ZipStorage.cs b/mcs/tools/monkeydoc/Monkeydoc/storage/ZipStorage.cs new file mode 100644 index 00000000000..81ed1c5bd66 --- /dev/null +++ b/mcs/tools/monkeydoc/Monkeydoc/storage/ZipStorage.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Xml; +using System.Linq; +using System.Text; +using System.Collections.Generic; + +using ICSharpCode.SharpZipLib.Zip; + +namespace MonkeyDoc.Storage +{ + public class ZipStorage : IDocStorage + { + string zipFileName; + int code; + ZipOutputStream zipOutput; + ZipFile zipFile; + // SharpZipLib use linear search to map name to index, correct that a bit + Dictionary entries = new Dictionary (); + + public ZipStorage (string zipFileName) + { + this.zipFileName = zipFileName; + } + + public bool SupportRevision { + get { + return false; + } + } + + public IDocRevisionManager RevisionManager { + get { + return null; + } + } + + public bool SupportChange { + get { + return true; + } + } + + public string Store (string id, string text) + { + EnsureOutput (); + SetupEntry (zipOutput, ref id); + var writer = new StreamWriter (zipOutput); + writer.Write (text); + writer.Flush (); + + return id; + } + + public string Store (string id, byte[] data) + { + EnsureOutput (); + SetupEntry (zipOutput, ref id); + zipOutput.Write (data, 0, data.Length); + return id; + } + + public string Store (string id, Stream stream) + { + EnsureOutput (); + SetupEntry (zipOutput, ref id); + stream.CopyTo (zipOutput); + return id; + } + + void SetupEntry (ZipOutputStream zipOutput, ref string id) + { + if (string.IsNullOrEmpty (id)) + id = GetNewCode (); + + ZipEntry entry = new ZipEntry (id); + zipOutput.PutNextEntry (entry); + } + + public Stream Retrieve (string id) + { + EnsureInput (); + int index; + ZipEntry entry; + if (!entries.TryGetValue (id, out index) || (entry = zipFile[index]) == null) + entry = zipFile.GetEntry (id); + if (entry != null) + return zipFile.GetInputStream (entry); + else + throw new ArgumentException ("id", string.Format ("'{0}' isn't a valid id for this storage", id)); + } + + public IEnumerable GetAvailableIds () + { + EnsureInput (); + return zipFile.Cast ().Select (ze => ze.Name); + } + + void EnsureOutput () + { + if (zipFile != null) + throw new InvalidOperationException ("This ZipStorage instance is already used in read-mode"); + if (zipOutput != null) + return; + zipOutput = new ZipOutputStream (File.Create (zipFileName)); + } + + void EnsureInput () + { + if (zipOutput != null) + throw new InvalidOperationException ("This ZipStorage instance is already used in write-mode"); + if (zipFile != null) + return; + zipFile = new ZipFile (zipFileName); + entries = Enumerable.Range (0, zipFile.Size).ToDictionary (i => zipFile[i].Name, i => i); + } + + public void Dispose () + { + if (zipOutput != null) + zipOutput.Dispose (); + if (zipFile != null) + zipFile.Close (); + } + + string GetNewCode () + { + return String.Format ("{0}", code++); + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Mono.Documentation/ManifestResourceResolver.cs b/mcs/tools/monkeydoc/Mono.Documentation/ManifestResourceResolver.cs new file mode 100644 index 00000000000..402d137e06f --- /dev/null +++ b/mcs/tools/monkeydoc/Mono.Documentation/ManifestResourceResolver.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Reflection; +using System.Xml; + +namespace Mono.Documentation { + public class ManifestResourceResolver : XmlUrlResolver { + private string[] dirs; + + public ManifestResourceResolver (params string[] dirs) + { + this.dirs = (string[]) dirs.Clone (); + } + + public override Uri ResolveUri (Uri baseUri, string relativeUri) + { + if (Array.IndexOf ( + Assembly.GetExecutingAssembly ().GetManifestResourceNames (), + relativeUri) >= 0) + return new Uri ("x-resource:///" + relativeUri); + foreach (var dir in dirs) { + if (File.Exists (Path.Combine (dir, relativeUri))) + return base.ResolveUri (new Uri ("file://" + new DirectoryInfo (dir).FullName + "/"), + relativeUri); + } + return base.ResolveUri (baseUri, relativeUri); + } + + public override object GetEntity (Uri absoluteUri, string role, Type ofObjectToReturn) + { + if (ofObjectToReturn == null) + ofObjectToReturn = typeof(Stream); + if (ofObjectToReturn != typeof(Stream)) + throw new XmlException ("This object type is not supported."); + if (absoluteUri.Scheme != "x-resource") + return base.GetEntity (absoluteUri, role, ofObjectToReturn); + return Assembly.GetExecutingAssembly().GetManifestResourceStream ( + absoluteUri.Segments [1]); + } + } +} + diff --git a/mcs/tools/monkeydoc/Mono.Documentation/XmlDocUtils.cs b/mcs/tools/monkeydoc/Mono.Documentation/XmlDocUtils.cs new file mode 100644 index 00000000000..2f4cd08f11a --- /dev/null +++ b/mcs/tools/monkeydoc/Mono.Documentation/XmlDocUtils.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Web; +using System.Xml; + +namespace Mono.Documentation { + + public delegate XmlDocument DocLoader (string escapedTypeName); + + public static class XmlDocUtils + { + public static XmlNodeList GetMemberGenericParameters (XmlNode member) + { + return member.SelectNodes ("Docs/typeparam"); + } + + public static XmlNodeList GetTypeGenericParameters (XmlNode member) + { + return member.SelectNodes ("/Type/TypeParameters/TypeParameter"); + } + + public static string ToTypeName (string type, XmlNode member) + { + return ToTypeName (type, GetTypeGenericParameters (member), + GetMemberGenericParameters (member)); + } + + public static string ToTypeName (string type, XmlNodeList typeGenParams, XmlNodeList memberGenParams) + { + type = type.Replace ("&", "@").Replace ("<", "{").Replace (">", "}"); + for (int i = 0; i < typeGenParams.Count; ++i) { + string name = typeGenParams [i].InnerText; + type = Regex.Replace (type, @"\b" + name + @"\b", "`" + i); + } + for (int i = 0; i < memberGenParams.Count; ++i) { + string name = memberGenParams [i].Attributes ["name"].Value; + type = Regex.Replace (type, @"\b" + name + @"\b", "``" + i); + } + return type; + } + + public static string ToEscapedTypeName (string name) + { + return GetCountedName (name, "`"); + } + + private static string GetCountedName (string name, string escape) + { + int lt = name.IndexOf ("<"); + if (lt == -1) + return name; + StringBuilder type = new StringBuilder (name.Length); + int start = 0; + do { + type.Append (name.Substring (start, lt - start)); + type.Append (escape); + type.Append (GetGenericCount (name, lt, out start)); + } while ((lt = name.IndexOf ('<', start)) >= 0); + if (start < name.Length) + type.Append (name.Substring (start)); + return type.ToString ().Replace ("+", "."); + } + + private static int GetGenericCount (string name, int start, out int end) + { + int n = 1; + bool r = true; + int i = start; + int depth = 1; + for ( ++i; r && i < name.Length; ++i) { + switch (name [i]) { + case ',': if (depth == 1) ++n; break; + case '<': ++depth; break; + case '>': --depth; if (depth == 0) r = false; break; + } + } + end = i; + return n; + } + + public static string ToEscapedMemberName (string member) + { + // Explicitly implemented interface members contain '.'s in the member + // name, e.g. System.Collections.Generic.IEnumerable
.GetEnumerator. + // CSC does a s/\./#/g for these. + member = member.Replace (".", "#"); + if (member [member.Length-1] == '>') { + int i = member.LastIndexOf ("<"); + int ignore; + return member.Substring (0, i).Replace ("<", "{").Replace (">", "}") + + "``" + GetGenericCount (member, i, out ignore); + } + return member.Replace ("<", "{").Replace (">", "}"); + } + + public static void AddExtensionMethods (XmlDocument typexml, ArrayList/**/ extensions, DocLoader loader) + { + // if no members (enum, delegate) don't add extensions + XmlNode m = typexml.SelectSingleNode ("/Type/Members"); + if (m == null) + return; + + // static classes can't be targets: + if (typexml.SelectSingleNode ( + "/Type/TypeSignature[@Language='C#']/@Value") + .Value.IndexOf (" static ") >= 0) + return; + + foreach (string s in GetSupportedTypes (typexml, loader)) { + foreach (XmlNode extension in extensions) { + bool add = false; + foreach (XmlNode target in extension.SelectNodes ("Targets/Target")) { + if (target.Attributes ["Type"].Value == s) { + add = true; + break; + } + } + if (!add) { + continue; + } + foreach (XmlNode c in extension.SelectNodes ("Member")) { + XmlNode cm = typexml.ImportNode (c, true); + m.AppendChild (cm); + } + } + } + } + + private static IEnumerable GetSupportedTypes (XmlDocument type, DocLoader loader) + { + yield return "System.Object"; + yield return GetEscapedPath (type, "Type/@FullName"); + + Hashtable h = new Hashtable (); + GetInterfaces (h, type, loader); + + string s = GetEscapedPath (type, "Type/Base/BaseTypeName"); + if (s != null) { + yield return s; + XmlDocument d; + string p = s; + while (s != null && (d = loader (s)) != null) { + GetInterfaces (h, d, loader); + s = GetEscapedPath (d, "Type/Base/BaseTypeName"); + if (p == s) + break; + yield return s; + } + } + + foreach (object o in h.Keys) + yield return o.ToString (); + } + + private static string GetEscapedPath (XmlDocument d, string path) + { + XmlNode n = d.SelectSingleNode (path); + if (n == null) + return null; + return "T:" + ToEscapedTypeName (n.InnerText); + } + + private static void GetInterfaces (Hashtable ifaces, XmlDocument doc, DocLoader loader) + { + foreach (XmlNode n in doc.SelectNodes ("Type/Interfaces/Interface/InterfaceName")) { + string t = ToEscapedTypeName (n.InnerText); + string tk = "T:" + t; + if (!ifaces.ContainsKey (tk)) { + ifaces.Add (tk, null); + try { + XmlDocument d = loader (t); + if (d != null) + GetInterfaces (ifaces, d, loader); + } + catch (FileNotFoundException e) { + // ignore; interface documentation couldn't be found. + } + } + } + } + + // Turns e.g. sources/netdocs into sources/cache/netdocs + public static string GetCacheDirectory (string assembledBase) + { + return Path.Combine ( + Path.Combine (Path.GetDirectoryName (assembledBase), "cache"), + Path.GetFileName (assembledBase)); + } + + public static string GetCachedFileName (string cacheDir, string url) + { + return Path.Combine (cacheDir, + Uri.EscapeUriString (url).Replace ('/', '+').Replace ("*", "%2a")); + } + } +} + diff --git a/mcs/tools/monkeydoc/Mono.Utilities/LRUCache.cs b/mcs/tools/monkeydoc/Mono.Utilities/LRUCache.cs new file mode 100644 index 00000000000..e479a9621ad --- /dev/null +++ b/mcs/tools/monkeydoc/Mono.Utilities/LRUCache.cs @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Mono.Utilities +{ + public class LRUCache + { + [ThreadStatic] + static LRUCache deflt; + + public static LRUCache Default { + get { + return deflt != null ? deflt : (deflt = new LRUCache (5)); + } + } + + int capacity; + LinkedList> list; + Dictionary>> lookup; + LinkedListNode> openNode; + + public LRUCache (int capacity) + { + this.capacity = capacity; + this.list = new LinkedList>(); + this.lookup = new Dictionary>> (capacity + 1); + this.openNode = new LinkedListNode>(new ListValueEntry (default(TKey), default(TValue))); + } + + public void Put (TKey key, TValue value) + { + if (Get(key) == null) { + this.openNode.Value.ItemKey = key; + this.openNode.Value.ItemValue = value; + this.list.AddFirst (this.openNode); + this.lookup.Add (key, this.openNode); + + if (this.list.Count > this.capacity) { + // last node is to be removed and saved for the next addition to the cache + this.openNode = this.list.Last; + + // remove from list & dictionary + this.list.RemoveLast(); + this.lookup.Remove(this.openNode.Value.ItemKey); + } else { + // still filling the cache, create a new open node for the next time + this.openNode = new LinkedListNode>(new ListValueEntry(default(TKey), default(TValue))); + } + } + } + + public TValue Get (TKey key) + { + LinkedListNode> node = null; + if (!this.lookup.TryGetValue (key, out node)) + return default (TValue); + this.list.Remove (node); + this.list.AddFirst (node); + return node.Value.ItemValue; + } + + class ListValueEntry where K : TKey + where V : TValue + { + internal V ItemValue; + internal K ItemKey; + + internal ListValueEntry(K key, V value) + { + this.ItemKey = key; + this.ItemValue = value; + } + } + } +} diff --git a/mcs/tools/monkeydoc/Mono.Utilities/MemoryLRU.cs b/mcs/tools/monkeydoc/Mono.Utilities/MemoryLRU.cs new file mode 100644 index 00000000000..8b7486149d8 --- /dev/null +++ b/mcs/tools/monkeydoc/Mono.Utilities/MemoryLRU.cs @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; + +namespace Mono.Utilities +{ + public class LRUCache + { + [ThreadStatic] + static LRUCache deflt; + + public static LRUCache Default { + get { + return deflt != null ? deflt : (deflt = new LRUCache (5)); + } + } + + int capacity; + LinkedList> list; + Dictionary>> lookup; + LinkedListNode> openNode; + + public LRUCache (int capacity) + { + this.capacity = capacity; + this.list = new LinkedList>(); + this.lookup = new Dictionary>> (capacity + 1); + this.openNode = new LinkedListNode>(new ListValueEntry (default(TKey), default(TValue))); + } + + public void Put (TKey key, TValue value) + { + if (Get(key) == null) { + this.openNode.Value.Itemkey = key; + this.openNode.Value.Itemvalue = value; + this.list.AddFirst (this.openNode); + this.lookup.Add (key, this.openNode); + + if (this.list.Count > this.capacity) { + // last node is to be removed and saved for the next addition to the cache + this.openNode = this.list.Last; + + // remove from list & dictionary + this.list.RemoveLast(); + this.lookup.Remove(this.openNode.Value.Itemkey); + } else { + // still filling the cache, create a new open node for the next time + this.openNode = new LinkedListNode>(new ListValueEntry(default(Tkey), default(Tvalue))); + } + } + } + + public TValue Get (TKey key) + { + LinkedListNode> node = null; + if (!this.lookup.TryGetValue (key, out node)) + return default (TValue); + this.list.Remove (node); + this.list.AddFirst (node); + return node.Value.ItemValue; + } + + class ListValueEntry where K : TKey + where V : TValue + { + internal V ItemValue; + internal K ItemKey; + + internal ListValueEntry(K key, V value) + { + this.ItemKey = key; + this.ItemValue = value; + } + } + } +} diff --git a/mcs/tools/monkeydoc/Mono.Utilities/colorizer.cs b/mcs/tools/monkeydoc/Mono.Utilities/colorizer.cs new file mode 100644 index 00000000000..74446241920 --- /dev/null +++ b/mcs/tools/monkeydoc/Mono.Utilities/colorizer.cs @@ -0,0 +1,171 @@ +using System; +using System.Text.RegularExpressions; +using System.Collections; + +namespace Mono.Utilities { + public class Colorizer { + // + // Syntax coloring + // + + static string keywords_cs = + "(\\babstract\\b|\\bevent\\b|\\bnew\\b|\\bstruct\\b|\\bas\\b|\\bexplicit\\b|\\bnull\\b|\\bswitch\\b|\\bbase\\b|\\bextern\\b|" + + + "\\bobject\\b|\\bthis\\b|\\bbool\\b|\\bfalse\\b|\\boperator\\b|\\bthrow\\b|\\bbreak\\b|\\bfinally\\b|\\bout\\b|\\btrue\\b|" + + + "\\bbyte\\b|\\bfixed\\b|\\boverride\\b|\\btry\\b|\\bcase\\b|\\bfloat\\b|\\bparams\\b|\\btypeof\\b|\\bcatch\\b|\\bfor\\b|" + + + "\\bprivate\\b|\\buint\\b|\\bchar\\b|\\bforeach\\b|\\bprotected\\b|\\bulong\\b|\\bchecked\\b|\\bgoto\\b|\\bpublic\\b|" + + + "\\bunchecked\\b|\\bclass\\b|\\bif\\b|\\breadonly\\b|\\bunsafe\\b|\\bconst\\b|\\bimplicit\\b|\\bref\\b|\\bushort\\b|" + + + "\\bcontinue\\b|\\bin\\b|\\breturn\\b|\\busing\\b|\\bdecimal\\b|\\bint\\b|\\bsbyte\\b|\\bvirtual\\b|\\bdefault\\b|" + + + "\\binterface\\b|\\bsealed\\b|\\bvolatile\\b|\\bdelegate\\b|\\binternal\\b|\\bshort\\b|\\bvoid\\b|\\bdo\\b|\\bis\\b|" + + + "\\bsizeof\\b|\\bwhile\\b|\\bdouble\\b|\\block\\b|\\bstackalloc\\b|\\belse\\b|\\blong\\b|\\bstatic\\b|\\benum\\b|" + + "\\bnamespace\\b|\\bstring\\b)"; + +#if false +// currently not in use + static string keywords_vb = + "(\\bAddHandler\\b|\\bAddressOf\\b|\\bAlias\\b|\\bAnd\\b|\\bAndAlso\\b|\\bAnsi\\b|\\bAs\\b|\\bAssembly\\b|" + + + "\\bAuto\\b|\\bBoolean\\b|\\bByRef\\b|\\bByte\\b|\\bByVal\\b|\\bCall\\b|\\bCase\\b|\\bCatch\\b|" + + + "\\bCBool\\b|\\bCByte\\b|\\bCChar\\b|\\bCDate\\b|\\bCDec\\b|\\bCDbl\\b|\\bChar\\b|\\bCInt\\b|" + + + "\\bClass\\b|\\bCLng\\b|\\bCObj\\b|\\bConst\\b|\\bCShort\\b|\\bCSng\\b|\\bCStr\\b|\\bCType\\b|" + + + "\\bDate\\b|\\bDecimal\\b|\\bDeclare\\b|\\bDefault\\b|\\bDelegate\\b|\\bDim\\b|\\bDirectCast\\b|\\bDo\\b|" + + + "\\bDouble\\b|\\bEach\\b|\\bElse\\b|\\bElseIf\\b|\\bEnd\\b|\\bEnum\\b|\\bErase\\b|\\bError\\b|" + + + "\\bEvent\\b|\\bExit\\b|\\bFalse\\b|\\bFinally\\b|\\bFor\\b|\\bFriend\\b|\\bFunction\\b|\\bGet\\b|" + + + "\\bGetType\\b|\\bGoSub\\b|\\bGoTo\\b|\\bHandles\\b|\\bIf\\b|\\bImplements\\b|\\bImports\\b|\\bIn\\b|" + + + "\\bInherits\\b|\\bInteger\\b|\\bInterface\\b|\\bIs\\b|\\bLet\\b|\\bLib\\b|\\bLike\\b|\\bLong\\b|" + + + "\\bLoop\\b|\\bMe\\b|\\bMod\\b|\\bModule\\b|\\bMustInherit\\b|\\bMustOverride\\b|\\bMyBase\\b|\\bMyClass\\b|" + + + "\\bNamespace\\b|\\bNew\\b|\\bNext\\b|\\bNot\\b|\\bNothing\\b|\\bNotInheritable\\b|\\bNotOverridable\\b|\\bObject\\b|" + + + "\\bOn\\b|\\bOption\\b|\\bOptional\\b|\\bOr\\b|\\bOrElse\\b|\\bOverloads\\b|\\bOverridable\\b|\\bOverrides\\b|" + + + "\\bParamArray\\b|\\bPreserve\\b|\\bPrivate\\b|\\bProperty\\b|\\bProtected\\b|\\bPublic\\b|\\bRaiseEvent\\b|\\bReadOnly\\b|" + + + "\\bReDim\\b|\\bREM\\b|\\bRemoveHandler\\b|\\bResume\\b|\\bReturn\\b|\\bSelect\\b|\\bSet\\b|\\bShadows\\b|" + + + "\\bShared\\b|\\bShort\\b|\\bSingle\\b|\\bStatic\\b|\\bStep\\b|\\bStop\\b|\\bString\\b|\\bStructure\\b|" + + + "\\bSub\\b|\\bSyncLock\\b|\\bThen\\b|\\bThrow\\b|\\bTo\\b|\\bTrue\\b|\\bTry\\b|\\bTypeOf\\b|" + + + "\\bUnicode\\b|\\bUntil\\b|\\bVariant\\b|\\bWhen\\b|\\bWhile\\b|\\bWith\\b|\\bWithEvents\\b|\\bWriteOnly\\b|\\bXor\\b)"; +#endif + + public static string Colorize(string text, string lang) + { + lang = lang.Trim().ToLower(); + switch (lang) { + case "xml": + return ColorizeXml(text); + case "cs": case "c#": case "csharp": + return ColorizeCs(text); + case "vb": + return ColorizeVb(text); + } + return Escape (text); + } + + static string ColorizeXml(string text) + { + // Order is highly important. + + // s/ / /g must be first, as later substitutions add required spaces + text = text.Replace(" ", " "); + + // Find & mark XML elements + Regex re = new Regex("<\\s*(\\/?)\\s*([\\s\\S]*?)\\s*(\\/?)\\s*>"); + text = re.Replace(text, "{blue:<$1}{maroon:$2}{blue:$3>}"); + + // Colorize attribute strings; must be done before colorizing marked XML + // elements so that we don't clobber the colorized XML tags. + re = new Regex ("([\"'])(.*?)\\1"); + text = re.Replace (text, + "$1$2$1"); + + // Colorize marked XML elements + re = new Regex("\\{(\\w*):([\\s\\S]*?)\\}"); + //text = re.Replace(text, "$2"); + text = re.Replace(text, "$2"); + + // Standard Structure + text = text.Replace("\t", "     "); + re = new Regex("\r\n|\r|\n"); + text = re.Replace(text, "
"); + + return text; + } + + static string ColorizeCs(string text) + { + text = text.Replace(" ", " "); + + text = text.Replace("<", "<"); + text = text.Replace(">", ">"); + + Regex re = new Regex("\"((((?!\").)|\\\")*?)\""); + + text = + re.Replace(text, + "\"$1\""); + //"\"$1\""); + + re = new + Regex + ("//(((.(?!\"))|\"(((?!\").)*)\")*)(\r|\n|\r\n)"); + //("//(((.(?!\"))|\"(((?!\").)*)\")*)(\r|\n|\r\n)"); + text = + re.Replace(text, + "//$1
"); + // "//$1
"); + + re = new Regex(keywords_cs); + text = re.Replace(text, "$1"); + //text = re.Replace(text, "$1"); + + text = text.Replace("\t", "     "); + text = text.Replace("\n", "
"); + + return text; + } + + static string ColorizeVb(string text) { + text = text.Replace(" ", " "); + + /* Regex re = new Regex ("\"((((?!\").)|\\\")*?)\""); + text = re.Replace (text,"\"$1\""); + + re = new Regex ("'(((.(?!\"\\<\\/span\\>))|\"(((?!\").)*)\"\\<\\/span\\>)*)(\r|\n|\r\n)"); + text = re.Replace (text,"//$1
"); + + re = new Regex (keywords_vb); + text = re.Replace (text,"$1"); + */ + text = text.Replace("\t", "     "); + text = text.Replace("\n", "
"); + return text; + } + + static string Escape(string text) + { + text = text.Replace("&", "&"); + text = text.Replace(" ", " "); + text = text.Replace("<", "<"); + text = text.Replace(">", ">"); + text = text.Replace("\n", "
"); + return text; + } + } +} diff --git a/mcs/tools/monkeydoc/Resources/.gitattributes b/mcs/tools/monkeydoc/Resources/.gitattributes new file mode 100644 index 00000000000..bfc0c0d4e98 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/.gitattributes @@ -0,0 +1 @@ +/helper.js -crlf diff --git a/mcs/tools/monkeydoc/Resources/Lminus.gif b/mcs/tools/monkeydoc/Resources/Lminus.gif new file mode 100644 index 00000000000..33c49d13036 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/Lminus.gif differ diff --git a/mcs/tools/monkeydoc/Resources/Lplus.gif b/mcs/tools/monkeydoc/Resources/Lplus.gif new file mode 100644 index 00000000000..9d2a2ac5c50 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/Lplus.gif differ diff --git a/mcs/tools/monkeydoc/Resources/base.css b/mcs/tools/monkeydoc/Resources/base.css new file mode 100644 index 00000000000..d264419b3cc --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/base.css @@ -0,0 +1,36 @@ +/* +* base.css: CSS applied to all the docs +* +* Author: Mario Sopena +*/ + +body, table { + margin: 0px; +} + +body, table, pre, p { + font-family: @@FONT_FAMILY@@, sans-serif; + /* font-size: @@FONT_SIZE@@pt; */ + font-size: 10pt; +} + +div.header { + background-color: #FAFBFD; + font-size: 1.7em; + font-weight: bold; + padding: 8px 0 0 10px; + font-family: 'Segoe UI',Verdana,Arial; +} + +div.title { + font-size: 130%; + font-weight: bolder; + margin-top: 0.3em; + margin-left: 0.2em; + margin-bottom: 0.1em; +} + +.subtitle { + font-style: italic; +} + diff --git a/mcs/tools/monkeydoc/Resources/ecmaspec-html-css.xsl b/mcs/tools/monkeydoc/Resources/ecmaspec-html-css.xsl new file mode 100644 index 00000000000..d9c4f7b07f6 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/ecmaspec-html-css.xsl @@ -0,0 +1,98 @@ + + + + + +
+
ECMA-334 C# Language Specification
+
: + (informative)
+
+ +
+ + +

+ +

+
+ + + + + + +
+ + + + + +
    + +
  • +
    +
+
+ + +
+
Code example
+ + + +
+
+ + + + + + + + +
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + (optional) + + + +
+ +
+
+ + +
+
+ + + + + + + + diff --git a/mcs/tools/monkeydoc/Resources/ecmaspec-html.xsl b/mcs/tools/monkeydoc/Resources/ecmaspec-html.xsl new file mode 100644 index 00000000000..631ee03a202 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/ecmaspec-html.xsl @@ -0,0 +1,96 @@ + + + + + + + +
+ ECMA-334 C# Language Specification + +

+ : + + + (informative) + +

+
+ + +
+ + +

+ +

+
+ + + + + + + + + + + + +
    + +
  • +
    +
+
+ + + + + + +
+
+		  
+	    
+
+
+ + + + + + + + +
+
+ + +
+ +
+
+
+
+ + + + + + + + + + + + opt + + + + + + + + +
diff --git a/mcs/tools/monkeydoc/Resources/ecmaspec.css b/mcs/tools/monkeydoc/Resources/ecmaspec.css new file mode 100644 index 00000000000..341f439b968 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/ecmaspec.css @@ -0,0 +1,69 @@ +/* +* ecmaspec.css: CSS applied to ECMA C# specs +* +* Author: Mario Sopena +*/ + +#ecmaspec { + background: #a4dda4; /*#83b183;*/ + border: 2px solid #556655; +} + +p { + text-align: justify; + margin-top: .5em; + margin-bottom: .5em; +} + +span.keyword { + color: #a6563a; +} + +a:link { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +div.code_example { + background: #f5f5dd; + border: 1px solid #cdcd82; + border: 1px solid black; + padding-left: 1em; + padding-bottom: 1em; + margin-top: 1em; + font-family: fixed; + white-space: pre; + margin-bottom: 1em; +} +div.code_ex_title { + position: relative; + top: -1em; + left: 30%; + background: #cdcd82; + border: 1px solid black; + color: black; + text-transform: uppercase; + width: 40%; + padding: 0.3em; + text-align: center; +} + +span.symbol { + font-weight: bolder; +} + + +span.optional { + font-style: italic; +} + +div.note { + background: #cdcd82; + border: 1px solid black; + padding: 1em; + margin-top: 1em; + margin-bottom: 1em; +} diff --git a/mcs/tools/monkeydoc/Resources/helper.js b/mcs/tools/monkeydoc/Resources/helper.js new file mode 100755 index 00000000000..2889c1b2165 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/helper.js @@ -0,0 +1,12 @@ +function toggle_display (block) { + var w = document.getElementById (block); + var t = document.getElementById (block + ":toggle"); + if (w.style.display == "none") { + w.style.display = "block"; + t.getElementsByTagName("img")[0].setAttribute ("src", "xtree/images/clean/Lminus.gif"); // + } else { + w.style.display = "none"; + t.getElementsByTagName("img")[0].setAttribute ("src", "xtree/images/clean/Lplus.gif"); // + } +} + diff --git a/mcs/tools/monkeydoc/Resources/home.html b/mcs/tools/monkeydoc/Resources/home.html new file mode 100644 index 00000000000..2d748a7e92e --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/home.html @@ -0,0 +1,69 @@ + + + + + +
+

The following documentation collections are available: + +

+
    + @@API_DOCS@@ +
+
+ +
+
Contributions
+
+
+ @@CONTRIBS@@ +
+
+

You have not made any contributions yet.

+

The Documentation of the libraries is not complete and your contributions would be greatly appreciated. The procedure is easy, browse to the part of the documentation you want to contribute to and click on the [Edit] link to start writing documentation.

+

When you are happy with your changes, use the Contributing--> Upload Contribution--> menu to send your contributions to our server.

+
+
diff --git a/mcs/tools/monkeydoc/Resources/images/bc_bg.png b/mcs/tools/monkeydoc/Resources/images/bc_bg.png new file mode 100644 index 00000000000..6f7bca783cf Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/bc_bg.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/bc_separator.png b/mcs/tools/monkeydoc/Resources/images/bc_separator.png new file mode 100644 index 00000000000..c137258bd72 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/bc_separator.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/error.png b/mcs/tools/monkeydoc/Resources/images/error.png new file mode 100644 index 00000000000..628cf2dae3d Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/error.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/hatch.png b/mcs/tools/monkeydoc/Resources/images/hatch.png new file mode 100644 index 00000000000..33bf2c2ecd7 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/hatch.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/headerbg.png b/mcs/tools/monkeydoc/Resources/images/headerbg.png new file mode 100644 index 00000000000..15575da474f Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/headerbg.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/help.png b/mcs/tools/monkeydoc/Resources/images/help.png new file mode 100644 index 00000000000..5c870176d4d Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/help.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/house.png b/mcs/tools/monkeydoc/Resources/images/house.png new file mode 100644 index 00000000000..fed62219f57 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/house.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/members.png b/mcs/tools/monkeydoc/Resources/images/members.png new file mode 100644 index 00000000000..4a8672bde48 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/members.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/namespace.png b/mcs/tools/monkeydoc/Resources/images/namespace.png new file mode 100644 index 00000000000..2bc1624cb46 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/namespace.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privclass.png b/mcs/tools/monkeydoc/Resources/images/privclass.png new file mode 100644 index 00000000000..bb0c8713cb4 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privclass.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privdelegate.png b/mcs/tools/monkeydoc/Resources/images/privdelegate.png new file mode 100644 index 00000000000..a5b470e3bdd Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privdelegate.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privenumeration.png b/mcs/tools/monkeydoc/Resources/images/privenumeration.png new file mode 100644 index 00000000000..df2c3c903ca Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privenumeration.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privevent.png b/mcs/tools/monkeydoc/Resources/images/privevent.png new file mode 100644 index 00000000000..e1d3887413e Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privevent.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privextension.png b/mcs/tools/monkeydoc/Resources/images/privextension.png new file mode 100644 index 00000000000..d336ddde38b Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privextension.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privfield.png b/mcs/tools/monkeydoc/Resources/images/privfield.png new file mode 100644 index 00000000000..0b246cf1505 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privfield.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privinterface.png b/mcs/tools/monkeydoc/Resources/images/privinterface.png new file mode 100644 index 00000000000..cde4b50fb52 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privinterface.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privmethod.png b/mcs/tools/monkeydoc/Resources/images/privmethod.png new file mode 100644 index 00000000000..d698426ff60 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privmethod.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privproperty.png b/mcs/tools/monkeydoc/Resources/images/privproperty.png new file mode 100644 index 00000000000..41a008d0efd Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privproperty.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/privstructure.png b/mcs/tools/monkeydoc/Resources/images/privstructure.png new file mode 100644 index 00000000000..ff064e61acd Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/privstructure.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protclass.png b/mcs/tools/monkeydoc/Resources/images/protclass.png new file mode 100644 index 00000000000..0c32ce00f0f Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protclass.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protdelegate.png b/mcs/tools/monkeydoc/Resources/images/protdelegate.png new file mode 100644 index 00000000000..ca44396891d Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protdelegate.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protenumeration.png b/mcs/tools/monkeydoc/Resources/images/protenumeration.png new file mode 100644 index 00000000000..14a4cf3d167 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protenumeration.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protevent.png b/mcs/tools/monkeydoc/Resources/images/protevent.png new file mode 100644 index 00000000000..613e88eb0fd Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protevent.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protextension.png b/mcs/tools/monkeydoc/Resources/images/protextension.png new file mode 100644 index 00000000000..f350d554b3a Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protextension.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protfield.png b/mcs/tools/monkeydoc/Resources/images/protfield.png new file mode 100644 index 00000000000..6e085535ee6 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protfield.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protinterface.png b/mcs/tools/monkeydoc/Resources/images/protinterface.png new file mode 100644 index 00000000000..4579a76ec2a Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protinterface.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protmethod.png b/mcs/tools/monkeydoc/Resources/images/protmethod.png new file mode 100644 index 00000000000..4ecb6ffe021 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protmethod.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protproperty.png b/mcs/tools/monkeydoc/Resources/images/protproperty.png new file mode 100644 index 00000000000..f79838aec15 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protproperty.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/protstructure.png b/mcs/tools/monkeydoc/Resources/images/protstructure.png new file mode 100644 index 00000000000..9b806ccd37c Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/protstructure.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubclass.png b/mcs/tools/monkeydoc/Resources/images/pubclass.png new file mode 100644 index 00000000000..75315583f96 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubclass.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubdelegate.png b/mcs/tools/monkeydoc/Resources/images/pubdelegate.png new file mode 100644 index 00000000000..19368a6b35e Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubdelegate.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubenumeration.png b/mcs/tools/monkeydoc/Resources/images/pubenumeration.png new file mode 100644 index 00000000000..9adab41f726 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubenumeration.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubevent.png b/mcs/tools/monkeydoc/Resources/images/pubevent.png new file mode 100644 index 00000000000..7abef6379d9 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubevent.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubextension.png b/mcs/tools/monkeydoc/Resources/images/pubextension.png new file mode 100644 index 00000000000..07253064960 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubextension.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubfield.png b/mcs/tools/monkeydoc/Resources/images/pubfield.png new file mode 100644 index 00000000000..c2fc5a2b363 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubfield.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubinterface.png b/mcs/tools/monkeydoc/Resources/images/pubinterface.png new file mode 100644 index 00000000000..050ea993730 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubinterface.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubmethod.png b/mcs/tools/monkeydoc/Resources/images/pubmethod.png new file mode 100644 index 00000000000..50ad06d6ca7 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubmethod.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubproperty.png b/mcs/tools/monkeydoc/Resources/images/pubproperty.png new file mode 100644 index 00000000000..2f0ef15dcfa Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubproperty.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/pubstructure.png b/mcs/tools/monkeydoc/Resources/images/pubstructure.png new file mode 100644 index 00000000000..161f2fcd671 Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/pubstructure.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/reference.png b/mcs/tools/monkeydoc/Resources/images/reference.png new file mode 100644 index 00000000000..9720bf8411a Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/reference.png differ diff --git a/mcs/tools/monkeydoc/Resources/images/treebg.png b/mcs/tools/monkeydoc/Resources/images/treebg.png new file mode 100644 index 00000000000..a5588a99a0b Binary files /dev/null and b/mcs/tools/monkeydoc/Resources/images/treebg.png differ diff --git a/mcs/tools/monkeydoc/Resources/mdoc-html-format.xsl b/mcs/tools/monkeydoc/Resources/mdoc-html-format.xsl new file mode 100644 index 00000000000..10acd9c3b6a --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mdoc-html-format.xsl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/mcs/tools/monkeydoc/Resources/mdoc-html-utils.xsl b/mcs/tools/monkeydoc/Resources/mdoc-html-utils.xsl new file mode 100644 index 00000000000..4403d0983fc --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mdoc-html-utils.xsl @@ -0,0 +1,2771 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + T: + + + + :Summary + + + + + + +

Mono Implementation Note:

+
+ +
+
+ + +

+ See Also: + + + T + + + + + /* + + + + Members + +

+
+ + + +

+ + + + + + + + + + + + T: + + + + + + + + +
+
+ + + + + +

+
+ +
+ + + + T: + + + + :Signature + + + + + + + + + [ + + ] +
+
+ + + [return: + + ] +
+
+ + + + + + + + + enum + + + + + + + + + + + + + + + + + + delegate + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + , + + + + , + + + + + + + + + + + + +
+ + + + + +
+
+
+
+ + + + + + + + + + < + + + [ + + ] + + + + + + + + + + , + + > + + + + + + + + + + + + + + + + + + + + + + + +
+ where + + : + + + + + + class + + + struct + + + , + + + + + , + + + , + + + , + new() + +
+ + + + +

+ + +

+ + +

Mono Implementation Note:

+
+ +
+
+ + + +

Value: + +

+
+ +
+ + + + + +

+
    + +
  • +
    +
+
+
+ + + + + + + + Minimum iOS version: + +
+
+ + + Minimum iOS version: + +
+
+
+
+
+ + + + + + + +

This is the default property for this class.

+
+ + + + + [ + + ] +
+
+ + + [return: + + ] +
+
+ + + + + + + event + + + + + + + + + + implicit operator + + + explicit operator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + operator+ + operator- + operator! + operator~ + operator++ + operator-- + operator true + operator false + operator+ + operator- + operator* + operator/ + operator% + operator& + operator| + operator^ + operator<< + operator>> + operator== + operator!= + operator> + operator< + operator>= + operator<= + + + + this + + + + + + + + + + + + + + + + + + + + + + + ( + [ + + + + + + + + , + + ) + ] + + + + + { + + } + + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + [ + + ] + + + + + + params + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + + + + + + +
+ +
+
+ + +
+
+
+
+
+
+ + + + + +
+ +
+
+ + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + F: + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Namespace: + +
+ Assembly: + + (in + + .dll) +
+ +
+ Assembly Versions: + + , + + +
+ +
+ Since: + + ; + + +
+ +
+ Since: + + ; + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + object + bool + byte + char + decimal + double + short + int + long + sbyte + float + string + ushort + uint + ulong + void + + + + + + + < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + C + M + P + F + E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ( + + + + + ) + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + ( + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + , + + + + + + + + + + + + + < + + + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + Extension Methods + Constructors + Properties + Methods + Fields + Events + Operators + Explicitly Implemented Interface Members + + + + + + extension methods + constructors + properties + methods + fields + events + operators + explicitly implemented interface members + + + + + + Class + Enumeration + Structure + Delegate + + + + + + + + + + + + + + Documentation for this section has not yet been entered. + + + + + + + + + + + +

+ +

+
+ + + + + + + + + + + + + + +
+ Note: + +
+
+ +
Operation
+ +
+ +
Note to Inheritors
+ +
+ +
Usage
+ +
+ + + + + + + +
+
+ + + + + + + + +

+ + + + + + + picture + + + +

+
+ + ¼ + π + θ + ≤ + ≥ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
  • + +
  • +
    +
+
+ +
    + +
  1. + +
  2. +
    +
+
+ + + [The '' type of list has not been implemented in the ECMA stylesheet.] + + + [The '' type of list has not been implemented in the ECMA stylesheet.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Protected + Public + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + + ( + + Inherited from + + + + + . + + ) + + + + + + + + + + [read-only] + + + [write-only] + + + +
default property
+
+ +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + , + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + : + + + + +
+ + +
+ +
+ + + + + + + + + + Conversion + + + From + + + + to + + + + + + + + + (Implicit) + + + (Explicit) + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + () + . + + + + + + + + +
+ +
+
+
+
+
+ +
+ +
+ + + + + + + + : + + + + + . + + + + + + + + + + + + + . + # + + + + + + + + + + + + + + + + + `` + + + + + + + + + + + + + ` + + + 1 + + + + + + + + + + + + + + + + + + + + + + + +!WTF? arglist=; rest= + + + + + + + + + + + + + + + + +!WTF 2? arglist=; rest= + + + + + + + + + + + + + + + + + + + +SkipTypeArgument: invalid type substring '' + + + + , + + + + + + + + + + + + + + + + + +! WTF3: s=; r= + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SkipGenericArgument: invalid type substring '' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ( + + , + + + + + + + ) + + + ~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + & + @ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + } + + + < + { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public + private + protected + internal + + + static + abstract + operator + + const + readonly + + + override + new + + + + sealed + virtual + + extern + checked + unsafe + volatile + explicit + implicit + + + + class + interface + struct + delegate + enum + + + + + + + Class + Interface + Struct + Delegate + Enum + + + + +

+ Note: This namespace, class, or member is supported only in version + and later. +

+
+ + + + + + + + + + + + + + javascript:alert("Documentation not found.") + + + + + +
diff --git a/mcs/tools/monkeydoc/Resources/mdoc-sections-css.xsl b/mcs/tools/monkeydoc/Resources/mdoc-sections-css.xsl new file mode 100644 index 00000000000..ab310431088 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mdoc-sections-css.xsl @@ -0,0 +1,131 @@ + + + + + + + + + + + + +

+ + + + + + +

+
+ +
+
+ + + + + + + + +

+ + + + + + + + + + + +

+
+ +
+
+ + + + + + + +

+ + + + + + +

+
+ +
+
+ + + + + + +
Member NameDescription
+
+ + + + + + + + + + + + +
+
+ + + + + +
+
+ + + +

Syntax

+
+ +
+
+ + + + + + +
TypeReason
+
+ +
+ diff --git a/mcs/tools/monkeydoc/Resources/mdoc-sections.xsl b/mcs/tools/monkeydoc/Resources/mdoc-sections.xsl new file mode 100644 index 00000000000..03d8383cf2b --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mdoc-sections.xsl @@ -0,0 +1,123 @@ + + + + + + + + + + + +

+ +

+
+ +
+
+ + + + + + + + +

+ +

+
+ +
+
+ + + + + + + +

+ +

+
+ +
+
+ + + + + + + + + +
Member NameDescription
+
+ + + + + + + +
+ +
+
+ + + + + + + + + +
+
+ + + + + +
+
+ + + + + +
+ + + +
+ +
+
+
+
+ + + + + + +
TypeReason
+
+ +
diff --git a/mcs/tools/monkeydoc/Resources/mono-ecma-css.xsl b/mcs/tools/monkeydoc/Resources/mono-ecma-css.xsl new file mode 100644 index 00000000000..017699de200 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mono-ecma-css.xsl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + +
+

Example

+
+
+				
+				
+			
+
+
+
+ +
diff --git a/mcs/tools/monkeydoc/Resources/mono-ecma-impl.xsl b/mcs/tools/monkeydoc/Resources/mono-ecma-impl.xsl new file mode 100644 index 00000000000..61d827ef11a --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mono-ecma-impl.xsl @@ -0,0 +1,540 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Master Overview + + + + + + + + + Members + + + + : + + Members + + + + + + + + + + + + + . + + + + + + + + + Namespace + + + + . Overloads + + + +
+
+
+ + +
+ + + + + + + + + + +

+ +

+
+
+ +
+ + + + +
+
+
+
+
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + +

+ The members of are listed below. +

+ + +

+ See Also: + + T:/* + Inherited members from + + +

+
+ + + + + + +
+ + + + +

+ The + + of are listed below. For a list of all members, see the + T:/* + Members list. +

+ + +

+ See Also: + + T:/* + Inherited members from + + +

+
+ + + + + + + + + + +
+ +
+ + +

+ The overloads of + are listed below. For a list of all members, see the + T:/* + Members list. +

+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ +
+ + + + + + +

+ + + + [Edit] + +

+ + + + +

Remarks

+
+ + + + [Edit] + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Don't know what to do! + + +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + T: + + + + + + + + + +
(in + + + + ) +
+ + + + + +
+ + +
+
+
+
+
+ +
+
+ + + + + + [Edit] + + + +
diff --git a/mcs/tools/monkeydoc/Resources/mono-ecma.css b/mcs/tools/monkeydoc/Resources/mono-ecma.css new file mode 100644 index 00000000000..2ffa1d2a5f8 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mono-ecma.css @@ -0,0 +1,596 @@ +body +{ + font-family: "Lucida Grande", Geneva, Helvetica, Arial, Verdana, Sans-Serif; + margin: 0; + padding: 0; + color: #333333; +} + +a:link +{ + color: #034af3; + text-decoration: underline; +} +a:visited +{ + color: #505abc; +} +a:hover +{ + color: #1d60ff; + text-decoration: none; +} +a:active +{ + color: #12eb87; +} + +pre +{ + font-family: Consolas, "Courier New", Monospace; + border: 1px solid #CCCCCC; + background-color: #F7F7F7; + padding: 7px; + margin: 0 20px 0 20px; + line-height: 1.3em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +img +{ + border: 0px; +} + +/* HEADINGS +----------------------------------------------------------*/ +h1, h2, h3, h4, h5, h6 +{ + color: #000; + font-family: Arial, Helvetica, sans-serif; +} + +h1 +{ + font-size: 16pt; + padding-bottom: 0; + margin-bottom: 0; +} +h2 +{ + font-size: 14pt; + padding: 0 0 1px 0; + border-bottom: 1px solid #DDDDDD; + margin-top: 20px; +} +h3 +{ + font-size: 12pt; + margin-top: 20px; + margin-bottom: 5px; +} +h4 +{ + font-size: 11pt; +} +h5, h6 +{ + font-size: 10pt; +} + +/* this rule styles

tags that are the +first child of the left and right table columns */ +.rightColumn > h1, .rightColumn > h2, .leftColumn > h1, .leftColumn > h2 +{ + margin-top: 0; +} + +/* PRIMARY LAYOUT ELEMENTS +----------------------------------------------------------*/ + +/* you can specify a greater or lesser percentage for the +page width. Or, you can specify an exact pixel width. */ +.page +{ + padding: 0; + margin: 0; +} + +#header +{ + position: relative; + margin-bottom: 0px; + color: #000; + padding: 0 0 0 15px; + background: url('mdocimages/headerbg.png'); + background-position: right; + background-repeat: no-repeat; + background-color: #679EF1; + height: 40px; + border-bottom: 1px solid #98C2F7; + border-bottom: 1px dotted #3363BD; +} + +#header h1 +{ + font-weight: bold; + padding: 0; + margin: 0; + color: #fff; + border: none; + line-height: 1.8em; + font-family: Arial, Helvetica, sans-serif; + font-size: 22px !important; +} + +#main +{ + padding: 0px 0px 15px 0px; + background-color: #fff; + margin-bottom: 30px; + _height: 1px; /* only IE6 applies CSS properties starting with an underscore */ +} + +#footer +{ + color: #999; + padding: 10px 0; + text-align: center; + line-height: normal; + margin: 0; + font-size: 8pt; +} + +#line-background +{ + background-image: url('mdocimages/treebg.png'); + background-repeat: repeat-y; + height: 100%; +} + +#left-content +{ + float: left; + width: 186px; + padding-top: 5px; + margin-right: 5px; + overflow: hidden; +} + +#right-content +{ + padding-top: 0px; + overflow: auto; + height: 100%; +} + +.right-content-pad +{ + margin: 6px 10px 0px 10px; +} + +.named-header +{ + background: url('mdocimages/hatch.png') repeat-x left bottom; + height: 48px; + background-color: #FAFBFD; + font-size: 16pt; + font-weight: bold; + padding: 8px 0 0 10px; + font-family: 'Segoe UI',Verdana,Arial, sans-serif; +} + +.member-list +{ + border-spacing: 0px; +} + +.member-list td +{ + padding: 4px; + margin: 0px; + border-bottom: 1px dotted #CCCCCC; +} + +.member-list +{ + +} +/* TAB MENU +----------------------------------------------------------*/ +ul#menu +{ + border-bottom: 1px #5C87B2 solid; + padding: 0 0 2px; + position: relative; + margin: 0; + text-align: right; +} + +ul#menu li +{ + display: inline; + list-style: none; +} + +ul#menu li#greeting +{ + padding: 10px 20px; + font-weight: bold; + text-decoration: none; + line-height: 2.8em; + color: #fff; +} + +ul#menu li a +{ + padding: 10px 20px; + font-weight: bold; + text-decoration: none; + line-height: 2.8em; + background-color: #e8eef4; + color: #034af3; +} + +ul#menu li a:hover +{ + background-color: #fff; + text-decoration: none; +} + +ul#menu li a:active +{ + background-color: #a6e2a6; + text-decoration: none; +} + +ul#menu li.selected a +{ + background-color: #fff; + color: #000; +} + +/* FORM LAYOUT ELEMENTS +----------------------------------------------------------*/ + +fieldset +{ + margin: 1em 0; + padding: 1em; + border: 1px solid #CCC; +} + +fieldset p +{ + margin: 2px 12px 10px 10px; +} + +legend +{ + font-size: 11pt; + font-weight: 600; + padding: 2px 4px 8px 4px; +} + +input[type="text"] +{ + width: 200px; + border: 1px solid #CCC; +} + +input[type="password"] +{ + width: 200px; + border: 1px solid #CCC; +} + +/* TABLE +----------------------------------------------------------*/ + +table +{ +/* border: solid 1px #e8eef4; + border-collapse: collapse;*/ +} + +table td +{ + padding: 5px; +/* border: solid 1px #e8eef4;*/ +} + +table th +{ + padding: 6px 5px; + text-align: left; + background-color: #e8eef4; + border: solid 1px #e8eef4; +} + +/* MISC +----------------------------------------------------------*/ +.clear +{ + clear: both; +} + +.error +{ + color:Red; +} + +.indent +{ + margin-left: 20px; + margin-right: 20px; +} + +#menucontainer +{ + margin-top:40px; +} + +div#title +{ + display:block; + float:left; + text-align:left; +} + +#logindisplay +{ + font-size:11pt; + display:block; + text-align:right; + margin:0px; + color:White; +} + +#logindisplay a:link +{ + color: white; + text-decoration: underline; +} + +#logindisplay a:visited +{ + color: white; + text-decoration: underline; +} + +#logindisplay a:hover +{ + color: white; + text-decoration: none; +} + +/* Styles for validation helpers +-----------------------------------------------------------*/ +.field-validation-error +{ + color: #ff0000; +} + +.field-validation-valid +{ + display: none; +} + +.input-validation-error +{ + border: 1px solid #ff0000; + background-color: #ffeeee; +} + +.validation-summary-errors +{ + font-weight: bold; + color: #ff0000; +} + +.validation-summary-valid +{ + display: none; +} + +/* Styles for editor and display helpers +----------------------------------------------------------*/ +.display-label, +.editor-label, +.display-field, +.editor-field +{ + margin: 0.5em 0; +} + +.text-box +{ + width: 30em; +} + +.text-box.multi-line +{ + height: 6.5em; +} + +.tri-state +{ + width: 6em; +} + +/* Breadcrumb Bar */ +.breadcrumb +{ + border-left: 1px solid #cacaca; + border-right: 1px solid #cacaca; + border-bottom: 1px solid #cacaca; + background-image: url('mdocimages/bc_bg.png'); + background-repeat: repeat-x; + height: 25px; + line-height: 25px; + color: #454545; + border-top: 0px; + width: 100%; + overflow: hidden; + margin-left: -2px; + padding: 0px; + font-style: normal; + font-variant: normal; + font-weight: normal; + font-size: 11px; + font-family: Arial, Helvetica, sans-serif; + margin-right: 0px; + margin-top: 0px; + margin-bottom: 0px; +} + +.breadcrumb li +{ + list-style-type: none; + float: left; + padding-left: 25px; + background-position: 5px center; + background-repeat: no-repeat; +} + +.breadcrumb li.pubclass { background-image: url('mdocimages/pubclass.png'); } +.breadcrumb li.pubdelegate { background-image: url('mdocimages/pubdelegate.png'); } +.breadcrumb li.pubenumeration { background-image: url('mdocimages/pubenumeration.png'); } +.breadcrumb li.pubevent { background-image: url('mdocimages/pubevent.png'); } +.breadcrumb li.pubextension { background-image: url('mdocimages/pubextension.png'); } +.breadcrumb li.pubfield { background-image: url('mdocimages/pubfield.png'); } +.breadcrumb li.pubinterface { background-image: url('mdocimages/pubinterface.png'); } +.breadcrumb li.pubmethod { background-image: url('mdocimages/pubmethod.png'); } +.breadcrumb li.pubproperty { background-image: url('mdocimages/pubproperty.png'); } +.breadcrumb li.pubstructure { background-image: url('mdocimages/pubstructure.png'); } + +.breadcrumb li.protclass { background-image: url('mdocimages/protclass.png'); } +.breadcrumb li.protdelegate { background-image: url('mdocimages/protdelegate.png'); } +.breadcrumb li.protenumeration { background-image: url('mdocimages/protenumeration.png'); } +.breadcrumb li.protevent { background-image: url('mdocimages/protevent.png'); } +.breadcrumb li.protextension { background-image: url('mdocimages/protextension.png'); } +.breadcrumb li.protfield { background-image: url('mdocimages/protfield.png'); } +.breadcrumb li.protinterface { background-image: url('mdocimages/protinterface.png'); } +.breadcrumb li.protmethod { background-image: url('mdocimages/protmethod.png'); } +.breadcrumb li.protproperty { background-image: url('mdocimages/protproperty.png'); } +.breadcrumb li.protstructure { background-image: url('mdocimages/protstructure.png'); } + +.breadcrumb li.privclass { background-image: url('mdocimages/privclass.png'); } +.breadcrumb li.privdelegate { background-image: url('mdocimages/privdelegate.png'); } +.breadcrumb li.privenumeration { background-image: url('mdocimages/privenumeration.png'); } +.breadcrumb li.privevent { background-image: url('mdocimages/privevent.png'); } +.breadcrumb li.privextension { background-image: url('mdocimages/privextension.png'); } +.breadcrumb li.privfield { background-image: url('mdocimages/privfield.png'); } +.breadcrumb li.privinterface { background-image: url('mdocimages/privinterface.png'); } +.breadcrumb li.privmethod { background-image: url('mdocimages/privmethod.png'); } +.breadcrumb li.privproperty { background-image: url('mdocimages/privproperty.png'); } +.breadcrumb li.privstructure { background-image: url('mdocimages/privstructure.png'); } + +.breadcrumb li.namespace +{ + padding-left: 26px; + background-image: url('mdocimages/namespace.png'); +} + +.breadcrumb li.reference +{ + padding-left: 26px; + background-image: url('mdocimages/reference.png'); +} + +.breadcrumb li.members +{ + padding-left: 24px; + background-image: url('mdocimages/members.png'); +} + +.breadcrumb li.home +{ + padding-left: 31px; + background-image: url('mdocimages/house.png'); + background-position: 8px center; +} + +.breadcrumb li.help +{ + background-image: url('mdocimages/help.png'); +} + +.breadcrumb li.unrecognized +{ + background-image: url('mdocimages/error.png'); +} + +.breadcrumb a +{ + height: 25px; + display: block; + background-image: url('mdocimages/bc_separator.png'); + background-repeat: no-repeat; + background-position: right; + padding-right: 15px; + color: #454545; + text-decoration: none; +} + +.breadcrumb a:hover +{ + text-decoration: underline; +} + +.clearer +{ + clear: both; +} + +div.Signature { + border: 1px solid #C0C0C0; + background: #F2F2F2; + padding: 1em; + margin-left: 1em; +} + +div.Content { + margin-left: 1em; +} + +.SectionBox { + margin-left: 1em; +} + +/* Salvaged from the old style */ +table.Documentation, table.Enumeration, table.TypeDocumentation { + border-collapse: collapse; + width: 100%; +} + +table.Documentation tr th, table.TypeMembers tr th, table.Enumeration tr th, table.TypeDocumentation tr th { + background: whitesmoke; + padding: 0.8em; + border: 1px solid gray; + text-align: left; + vertical-align: bottom; +} + +table.Documentation tr td, table.TypeMembers tr td, table.Enumeration tr td, table.TypeDocumentation tr td { + padding: 0.5em; + border: 1px solid gray; + text-align: left; + vertical-align: top; +} + +table.TypeMembers { + border: 1px solid #C0C0C0; + width: 100%; +} + +table.TypeMembers tr td { + background: #F8F8F8; + border: white; +} + +span.NotEntered /* Documentation for this section has not yet been entered */ { + font-style: italic; + color: #aaa; +} diff --git a/mcs/tools/monkeydoc/Resources/mono-ecma.xsl b/mcs/tools/monkeydoc/Resources/mono-ecma.xsl new file mode 100644 index 00000000000..76356d2f13e --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/mono-ecma.xsl @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + +
Example
+ +
+						
+					
+
+
+ +
diff --git a/mcs/tools/monkeydoc/Resources/toc-html.xsl b/mcs/tools/monkeydoc/Resources/toc-html.xsl new file mode 100644 index 00000000000..ea4d564e613 --- /dev/null +++ b/mcs/tools/monkeydoc/Resources/toc-html.xsl @@ -0,0 +1,32 @@ + + + + + +

+ +
+ + +

+
+ + +
    + +
+
+ + + + +
  • + +
  • +
    + +
  • +
    +
    +
    +
    \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Test/Monkeydoc.Ecma/EcmaUrlTests.cs b/mcs/tools/monkeydoc/Test/Monkeydoc.Ecma/EcmaUrlTests.cs new file mode 100644 index 00000000000..611e1050ae7 --- /dev/null +++ b/mcs/tools/monkeydoc/Test/Monkeydoc.Ecma/EcmaUrlTests.cs @@ -0,0 +1,444 @@ +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; + +using NUnit.Framework; + +using MonkeyDoc; +using Monkeydoc.Ecma; + +namespace MonoTests.MonkeyDoc.Ecma +{ + [TestFixture] + public class EcmaUrlTests + { + EcmaUrlParser parser; + + [SetUp] + public void Setup () + { + parser = new EcmaUrlParser (); + } + + void AssertValidUrl (string url) + { + try { + parser.IsValid (url); + } catch { + Assert.Fail (string.Format ("URL '{0}' deemed not valid", url)); + } + } + + void AssertInvalidUrl (string url) + { + try { + parser.IsValid (url); + } catch { + return; + } + Assert.Fail (string.Format ("URL '{0}' deemed valid", url)); + } + + void AssertUrlDesc (EcmaDesc expected, string url) + { + EcmaDesc actual = null; + try { + actual = parser.Parse (url); + } catch (Exception e) { + Assert.Fail (string.Format ("URL '{0}' deemed not valid: {1}{2}", url, Environment.NewLine, e.ToString ())); + } + + Assert.AreEqual (expected, actual, "Converted URL differs"); + } + + [Test] + public void CommonMethodUrlIsValidTest () + { + AssertValidUrl ("M:System.String.FooBar()"); + AssertValidUrl ("M:System.String.FooBar(System.String, Int32)"); + AssertValidUrl ("M:System.Foo.Int32>>.Foo()"); + AssertValidUrl ("M:System.Foo.Int32>>.Foo(Bleh,Bar)"); + AssertValidUrl ("M:System.Foo.Int32>>.Foo(Bleh,Bar)"); + AssertValidUrl ("M:Gendarme.Framework.Helpers.Log.WriteLine(string,string,object[])"); + AssertValidUrl ("M:Mono.Security.X509.Extensions.SubjectKeyIdentifierExtension.Decode"); + AssertValidUrl ("M:Mono.Security.PKCS7.IssuerAndSerialNumber"); + } + + [Test] + public void CommonTypeUrlIsValidTest () + { + AssertValidUrl ("T:Int32"); + AssertValidUrl ("T:System.Foo.Int32"); + AssertValidUrl ("T:System.Foo.Int32"); + AssertValidUrl ("T:System.Foo.Int32>>"); + AssertValidUrl ("T:System.Foo.Int32"); + AssertValidUrl ("T:System.Foo.Int32"); + AssertValidUrl ("T:System.Foo.Int32>>"); + AssertValidUrl ("T:System.Foo.Int32>>"); + } + + [Test] + public void CommonTypeUrlNotValidTest () + { + AssertInvalidUrl ("TInt32"); + AssertInvalidUrl ("K:Int32"); + AssertInvalidUrl ("T:System..Foo.Int32"); + AssertInvalidUrl ("T:System.Foo.Int32>>"); + AssertInvalidUrl ("T:System.Foo.Int32"); + AssertInvalidUrl ("T:System.Foo.Int32<+FooBar>>"); + } + + [Test] + public void NamespaceValidTest () + { + AssertValidUrl ("N:Foo.Bar"); + AssertValidUrl ("N:Foo"); + AssertValidUrl ("N:Foo.Bar.Baz"); + AssertValidUrl ("N:A.B.C"); + + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Namespace, + Namespace = "Foo.Bar.Blop" }; + AssertUrlDesc (ast, "N:Foo.Bar.Blop"); + } + + [Test] + public void ConstructorValidTest () + { + AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule"); + AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule()"); + AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule(System.String)"); + AssertValidUrl ("C:Gendarme.Framework.Helpers.MethodSignature.MethodSignature(string,string,string[],System.Func)"); + AssertValidUrl ("C:System.Collections.Generic.Dictionary+KeyCollection.KeyCollection(System.Collections.Generic.Dictionary)"); + } + + [Test] + public void SlashExpressionValidTest () + { + AssertValidUrl ("T:Foo.Bar.Type/*"); + AssertValidUrl ("T:Foo.Bar.Type/M"); + AssertValidUrl ("T:Gendarme.Framework.Bitmask/M/Equals"); + AssertValidUrl ("T:Gendarme.Framework.Helpers.Log/M/WriteLine"); + AssertValidUrl ("T:System.Windows.Forms.AxHost/M/System.ComponentModel.ICustomTypeDescriptor.GetEvents"); + } + + [Test] + public void MethodWithArgModValidTest () + { + AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging&)"); + AssertValidUrl ("M:Foo.Bar.FooBar(int@, System.Drawing.Imaging)"); + AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging*)"); + AssertValidUrl ("M:Foo.Bar.FooBar(int*, System.Drawing.Imaging&)"); + AssertValidUrl ("M:Atk.NoOpObject.GetRunAttributes(int,int&,int&)"); + } + + [Test] + public void MethodWithJaggedArrayArgsValidTest () + { + AssertValidUrl ("M:System.Reflection.Emit.SignatureHelper.GetPropertySigHelper(System.Reflection.Module,System.Reflection.CallingConventions,Type,Type[],Type[],Type[],Type[][],Type[][])"); + } + + [Test] + public void MethodWithInnerTypeValidTest () + { + AssertValidUrl ("M:System.TimeZoneInfo+AdjustmentRule.CreateAdjustmentRule"); + } + + [Test] + public void FieldValidTest () + { + AssertValidUrl ("F:Mono.Terminal.Curses.KeyF10"); + AssertValidUrl ("F:Novell.Directory.Ldap.Utilclass.ExceptionMessages.NOT_IMPLEMENTED"); + AssertValidUrl ("F:Novell.Directory.Ldap.LdapException.NOT_ALLOWED_ON_NONLEAF"); + } + + [Test] + public void PropertyValidTest () + { + AssertValidUrl ("P:System.Foo.Bar"); + AssertValidUrl ("P:System.ArraySegment.Array"); + } + + [Test] + public void IndexPropertyValidTest () + { + AssertValidUrl ("P:System.ComponentModel.PropertyDescriptorCollection.Item(int)"); + AssertValidUrl ("P:System.ComponentModel.AttributeCollection.Item(Type)"); + AssertValidUrl ("P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)"); + AssertValidUrl ("P:System.Collections.Specialized.BitVector32.Item(System.Collections.Specialized.BitVector32+Section)"); + } + + [Test] + public void ExplicitMethodImplValidTest () + { + AssertValidUrl ("M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose"); + } + + [Test] + public void MetaEtcNodeTest () + { + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type, + Namespace = "Foo.Bar", + TypeName = "Type", + Etc = '*' }; + AssertUrlDesc (ast, "T:Foo.Bar.Type/*"); + } + + [Test] + public void MetaEtcWithInnerTypeTest () + { + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type, + Namespace = "Novell.Directory.Ldap", + TypeName = "Connection", + NestedType = new EcmaDesc { DescKind = EcmaDesc.Kind.Type, TypeName = "ReaderThread" }, + Etc = '*' }; + AssertUrlDesc (ast, "T:Novell.Directory.Ldap.Connection+ReaderThread/*"); + } + + [Test] + public void SimpleTypeUrlParseTest () + { + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type, + TypeName = "String", + Namespace = "System" }; + AssertUrlDesc (ast, "T:System.String"); + } + + [Test] + public void TypeWithOneGenericUrlParseTest () + { + var generics = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = string.Empty, + TypeName = "T" + } + }; + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type, + TypeName = "String", + Namespace = "System", + GenericTypeArguments = generics, + }; + + AssertUrlDesc (ast, "T:System.String"); + } + + [Test] + public void TypeWithNestedGenericUrlParseTest () + { + var generics = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "T", + Namespace = string.Empty + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.Collections.Generic", + TypeName = "List", + GenericTypeArguments = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "V", + Namespace = string.Empty + } + } + } + }; + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type, + TypeName = "String", + Namespace = "System", + GenericTypeArguments = generics, + }; + + AssertUrlDesc (ast, "T:System.String>"); + } + + [Test] + public void SimpleMethodUrlParseTest () + { + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method, + TypeName = "String", + Namespace = "System", + MemberName = "FooBar" + }; + AssertUrlDesc (ast, "M:System.String.FooBar()"); + } + + [Test] + public void MethodWithArgsUrlParseTest () + { + var args = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "String" + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Int32", + Namespace = string.Empty + } + }; + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method, + TypeName = "String", + Namespace = "System", + MemberName = "FooBar", + MemberArguments = args + }; + AssertUrlDesc (ast, "M:System.String.FooBar(System.String, Int32)"); + } + + [Test] + public void MethodWithArgsAndGenericsUrlParseTest () + { + var args = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "String" + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System.Collections.Generic", + TypeName = "Dictionary", + GenericTypeArguments = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "K", + Namespace = string.Empty + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "V", + Namespace = string.Empty + } + } + } + }; + + var generics = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Action", + Namespace = string.Empty, + GenericTypeArguments = new[] { + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + Namespace = "System", + TypeName = "Single", + }, + new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "int", + Namespace = string.Empty + }, + } + } + }; + + var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method, + TypeName = "String", + Namespace = "System", + MemberName = "FooBar", + MemberArguments = args, + GenericMemberArguments = generics + }; + AssertUrlDesc (ast, "M:System.String.FooBar>(System.String, System.Collections.Generic.Dictionary)"); + } + + [Test] + public void ExplicitMethodImplementationParseTest () + { + var inner = new EcmaDesc { + MemberName = "Dispose", + TypeName = "IDisposable", + Namespace = "System" + }; + var ast = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + TypeName = "RegistryKey", + Namespace = "Microsoft.Win32", + ExplicitImplMember = inner + }; + AssertUrlDesc (ast, "M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose"); + } + + [Test] + public void SimpleMethodWithNumberInType () + { + var ast = new EcmaDesc { + DescKind = EcmaDesc.Kind.Method, + TypeName = "ASN1", + Namespace = "Mono.Security", + MemberName = "Add" + }; + AssertUrlDesc (ast, "M:Mono.Security.ASN1.Add"); + } + + [Test] + public void JaggedArrayWithDimensions () + { + var ast = new EcmaDesc { + DescKind = EcmaDesc.Kind.Type, + TypeName = "Int32", + Namespace = "System", + ArrayDimensions = new int[] { 3, 1, 1 } + }; + AssertUrlDesc (ast, "T:System.Int32[,,][][]"); + } + + [Test] + public void ExplicitIndexerImplementation () + { + var explicitImpl = new EcmaDesc { + Namespace = "System.Web.SessionState", + TypeName = "IHttpSessionState", + MemberName = "Item", + MemberArguments = new [] { new EcmaDesc { DescKind = EcmaDesc.Kind.Type, Namespace = "System", TypeName = "Int32" } }, + }; + var ast = new EcmaDesc { + DescKind = EcmaDesc.Kind.Property, + TypeName = "HttpSessionStateContainer", + Namespace = "System.Web.SessionState", + ExplicitImplMember = explicitImpl, + }; + AssertUrlDesc (ast, "P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)"); + } + + /* [Test] + public void TreeParsabilityTest () + { + var rootTree = RootTree.LoadTree ("/home/jeremie/monodoc/"); + Node result; + var generator = new CheckGenerator (); + + foreach (var leaf in GetLeaves (rootTree.RootNode).Where (IsEcmaNode)) + AssertUrl (leaf.PublicUrl); + } + + IEnumerable GetLeaves (Node node) + { + if (node == null) + yield break; + + if (node.IsLeaf) + yield return node; + else { + foreach (var child in node.Nodes) { + if (!string.IsNullOrEmpty (child.Element) && !child.Element.StartsWith ("root:/")) + yield return child; + foreach (var childLeaf in GetLeaves (child)) + yield return childLeaf; + } + } + } + + bool IsEcmaNode (Node node) + { + var url = node.PublicUrl; + return url != null && url.Length > 2 && url[1] == ':'; + }*/ + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Test/Monkeydoc/HelpSourceTests.cs b/mcs/tools/monkeydoc/Test/Monkeydoc/HelpSourceTests.cs new file mode 100644 index 00000000000..354fe91f4dd --- /dev/null +++ b/mcs/tools/monkeydoc/Test/Monkeydoc/HelpSourceTests.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using System.Linq; +using System.Collections.Generic; + +using NUnit.Framework; + +using MonkeyDoc; + +namespace MonoTests.MonkeyDoc +{ + [TestFixture] + public class HelpSourceTest + { + const string BaseDir = "../../tools/monkeydoc/Test/monodoc/"; + + class CheckGenerator : IDocGenerator + { + public string LastCheckMessage { get; set; } + + public bool Generate (HelpSource hs, string id) + { + LastCheckMessage = string.Format ("#1 : {0} {1}", hs, id); + if (hs == null || string.IsNullOrEmpty (id)) + return false; + + // Stripe the arguments parts since we don't need it + var argIdx = id.LastIndexOf ('?'); + if (argIdx != -1) + id = id.Substring (0, argIdx); + + LastCheckMessage = string.Format ("#2 : {0} {1}", hs, id); + if (hs.IsRawContent (id)) + return hs.GetText (id) != null; + + IEnumerable parts; + if (hs.IsMultiPart (id, out parts)) { + LastCheckMessage = string.Format ("#4 : {0} {1} ({2})", hs, id, string.Join (", ", parts)); + foreach (var partId in parts) + if (!Generate (hs, partId)) + return false; + } + + LastCheckMessage = string.Format ("#3 : {0} {1}", hs, id); + if (hs.IsGeneratedContent (id)) + return hs.GetCachedText (id) != null; + else { + var s = hs.GetCachedHelpStream (id); + if (s != null) { + s.Close (); + return true; + } else { + return false; + } + } + } + } + + /* This test verifies that for every node in our tree that possed a PublicUrl, + * we can correctly access it back through RenderUrl + */ + [Test] + public void ReachabilityTest () + { + var rootTree = RootTree.LoadTree (Path.GetFullPath (BaseDir), false); + Node result; + var generator = new CheckGenerator (); + int errorCount = 0; + int testCount = 0; + + foreach (var leaf in GetLeaves (rootTree.RootNode)) { + if (!rootTree.RenderUrl (leaf.PublicUrl, generator, out result) || leaf != result) { + Console.WriteLine ("Error: {0} with HelpSource {1} ", leaf.PublicUrl, leaf.Tree.HelpSource.Name); + errorCount++; + } + testCount++; + } + + Assert.AreEqual (0, errorCount, errorCount + " / " + testCount.ToString ()); + } + + IEnumerable GetLeaves (Node node) + { + if (node == null) + yield break; + + if (node.IsLeaf) + yield return node; + else { + foreach (var child in node.Nodes) { + if (!string.IsNullOrEmpty (child.Element) && !child.Element.StartsWith ("root:/")) + yield return child; + foreach (var childLeaf in GetLeaves (child)) + yield return childLeaf; + } + } + } + } +} \ No newline at end of file diff --git a/mcs/tools/monkeydoc/Test/monodoc/monodoc.xml b/mcs/tools/monkeydoc/Test/monodoc/monodoc.xml new file mode 100644 index 00000000000..94a4b222e80 --- /dev/null +++ b/mcs/tools/monkeydoc/Test/monodoc/monodoc.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mcs/tools/monkeydoc/monkeydoc.dll.config.in b/mcs/tools/monkeydoc/monkeydoc.dll.config.in new file mode 100644 index 00000000000..251f7789fe8 --- /dev/null +++ b/mcs/tools/monkeydoc/monkeydoc.dll.config.in @@ -0,0 +1,6 @@ + + + + + + diff --git a/mcs/tools/monkeydoc/monkeydoc.dll.sources b/mcs/tools/monkeydoc/monkeydoc.dll.sources new file mode 100644 index 00000000000..53ee97f24e6 --- /dev/null +++ b/mcs/tools/monkeydoc/monkeydoc.dll.sources @@ -0,0 +1,463 @@ +Assembly/AssemblyInfo.cs +Monkeydoc/SearchableIndex.cs +Monkeydoc/SearchableDocument.cs +Monkeydoc/storage/ZipStorage.cs +Monkeydoc/providers/man-provider.cs +Monkeydoc/providers/ecmaspec-provider.cs +Monkeydoc/providers/error-provider.cs +Monkeydoc/providers/xhtml-provider.cs +Monkeydoc/providers/ecma-provider.cs +Monkeydoc/providers/addins-provider.cs +Monkeydoc/HelpSource.cs +Monkeydoc/Tree.cs +Monkeydoc/Node.cs +Monkeydoc/generator.cs +Monkeydoc/caches/NullCache.cs +Monkeydoc/caches/FileCache.cs +Monkeydoc/storage.cs +Monkeydoc/Provider.cs +Monkeydoc/cache.cs +Monkeydoc/index.cs +Monkeydoc/RootTree.cs +Monkeydoc/TypeUtils.cs +Monkeydoc/generators/html/Man2Html.cs +Monkeydoc/generators/html/Toc2Html.cs +Monkeydoc/generators/html/Ecmaspec2Html.cs +Monkeydoc/generators/html/Error2Html.cs +Monkeydoc/generators/html/MonoBook2Html.cs +Monkeydoc/generators/html/Ecma2Html.cs +Monkeydoc/generators/html/Addin2Html.cs +Monkeydoc/generators/html/Idem.cs +Monkeydoc/generators/HtmlGenerator.cs +Mono.Utilities/colorizer.cs +Mono.Utilities/LRUCache.cs +Monkeydoc.Ecma/EcmaUrlParser.cs +Monkeydoc.Ecma/EcmaUrlTokenizer.cs +Monkeydoc.Ecma/EcmaDesc.cs +Mono.Documentation/ManifestResourceResolver.cs +Mono.Documentation/XmlDocUtils.cs +../../../external/Lucene.Net/src/core/Analysis/Analyzer.cs +../../../external/Lucene.Net/src/core/Analysis/ASCIIFoldingFilter.cs +../../../external/Lucene.Net/src/core/Analysis/BaseCharFilter.cs +../../../external/Lucene.Net/src/core/Analysis/CachingTokenFilter.cs +../../../external/Lucene.Net/src/core/Analysis/CharArraySet.cs +../../../external/Lucene.Net/src/core/Analysis/CharFilter.cs +../../../external/Lucene.Net/src/core/Analysis/CharReader.cs +../../../external/Lucene.Net/src/core/Analysis/CharStream.cs +../../../external/Lucene.Net/src/core/Analysis/CharTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/ISOLatin1AccentFilter.cs +../../../external/Lucene.Net/src/core/Analysis/KeywordAnalyzer.cs +../../../external/Lucene.Net/src/core/Analysis/KeywordTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/LengthFilter.cs +../../../external/Lucene.Net/src/core/Analysis/LetterTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/LowerCaseFilter.cs +../../../external/Lucene.Net/src/core/Analysis/LowerCaseTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/MappingCharFilter.cs +../../../external/Lucene.Net/src/core/Analysis/NormalizeCharMap.cs +../../../external/Lucene.Net/src/core/Analysis/NumericTokenStream.cs +../../../external/Lucene.Net/src/core/Analysis/PerFieldAnalyzerWrapper.cs +../../../external/Lucene.Net/src/core/Analysis/PorterStemFilter.cs +../../../external/Lucene.Net/src/core/Analysis/PorterStemmer.cs +../../../external/Lucene.Net/src/core/Analysis/SimpleAnalyzer.cs +../../../external/Lucene.Net/src/core/Analysis/Standard/StandardAnalyzer.cs +../../../external/Lucene.Net/src/core/Analysis/Standard/StandardFilter.cs +../../../external/Lucene.Net/src/core/Analysis/Standard/StandardTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/Standard/StandardTokenizerImpl.cs +../../../external/Lucene.Net/src/core/Analysis/StopAnalyzer.cs +../../../external/Lucene.Net/src/core/Analysis/StopFilter.cs +../../../external/Lucene.Net/src/core/Analysis/TeeSinkTokenFilter.cs +../../../external/Lucene.Net/src/core/Analysis/Token.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/FlagsAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/IFlagsAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/IOffsetAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/IPayloadAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/IPositionIncrementAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/ITermAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/ITypeAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/OffsetAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/PayloadAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/PositionIncrementAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/TermAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenattributes/TypeAttribute.cs +../../../external/Lucene.Net/src/core/Analysis/TokenFilter.cs +../../../external/Lucene.Net/src/core/Analysis/Tokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/TokenStream.cs +../../../external/Lucene.Net/src/core/Analysis/WhitespaceAnalyzer.cs +../../../external/Lucene.Net/src/core/Analysis/WhitespaceTokenizer.cs +../../../external/Lucene.Net/src/core/Analysis/WordlistLoader.cs +../../../external/Lucene.Net/src/core/Document/AbstractField.cs +../../../external/Lucene.Net/src/core/Document/CompressionTools.cs +../../../external/Lucene.Net/src/core/Document/DateField.cs +../../../external/Lucene.Net/src/core/Document/DateTools.cs +../../../external/Lucene.Net/src/core/Document/Document.cs +../../../external/Lucene.Net/src/core/Document/Field.cs +../../../external/Lucene.Net/src/core/Document/Fieldable.cs +../../../external/Lucene.Net/src/core/Document/FieldSelector.cs +../../../external/Lucene.Net/src/core/Document/FieldSelectorResult.cs +../../../external/Lucene.Net/src/core/Document/LoadFirstFieldSelector.cs +../../../external/Lucene.Net/src/core/Document/MapFieldSelector.cs +../../../external/Lucene.Net/src/core/Document/NumberTools.cs +../../../external/Lucene.Net/src/core/Document/NumericField.cs +../../../external/Lucene.Net/src/core/Document/SetBasedFieldSelector.cs +../../../external/Lucene.Net/src/core/Index/AbstractAllTermDocs.cs +../../../external/Lucene.Net/src/core/Index/AllTermDocs.cs +../../../external/Lucene.Net/src/core/Index/BufferedDeletes.cs +../../../external/Lucene.Net/src/core/Index/ByteBlockPool.cs +../../../external/Lucene.Net/src/core/Index/ByteSliceReader.cs +../../../external/Lucene.Net/src/core/Index/ByteSliceWriter.cs +../../../external/Lucene.Net/src/core/Index/CharBlockPool.cs +../../../external/Lucene.Net/src/core/Index/CheckIndex.cs +../../../external/Lucene.Net/src/core/Index/CompoundFileReader.cs +../../../external/Lucene.Net/src/core/Index/CompoundFileWriter.cs +../../../external/Lucene.Net/src/core/Index/ConcurrentMergeScheduler.cs +../../../external/Lucene.Net/src/core/Index/CorruptIndexException.cs +../../../external/Lucene.Net/src/core/Index/DefaultSkipListReader.cs +../../../external/Lucene.Net/src/core/Index/DefaultSkipListWriter.cs +../../../external/Lucene.Net/src/core/Index/DirectoryReader.cs +../../../external/Lucene.Net/src/core/Index/DocConsumer.cs +../../../external/Lucene.Net/src/core/Index/DocConsumerPerThread.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumer.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumerPerField.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumerPerThread.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumers.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumersPerField.cs +../../../external/Lucene.Net/src/core/Index/DocFieldConsumersPerThread.cs +../../../external/Lucene.Net/src/core/Index/DocFieldProcessor.cs +../../../external/Lucene.Net/src/core/Index/DocFieldProcessorPerField.cs +../../../external/Lucene.Net/src/core/Index/DocFieldProcessorPerThread.cs +../../../external/Lucene.Net/src/core/Index/DocInverter.cs +../../../external/Lucene.Net/src/core/Index/DocInverterPerField.cs +../../../external/Lucene.Net/src/core/Index/DocInverterPerThread.cs +../../../external/Lucene.Net/src/core/Index/DocumentsWriter.cs +../../../external/Lucene.Net/src/core/Index/DocumentsWriterThreadState.cs +../../../external/Lucene.Net/src/core/Index/FieldInfo.cs +../../../external/Lucene.Net/src/core/Index/FieldInfos.cs +../../../external/Lucene.Net/src/core/Index/FieldInvertState.cs +../../../external/Lucene.Net/src/core/Index/FieldReaderException.cs +../../../external/Lucene.Net/src/core/Index/FieldSortedTermVectorMapper.cs +../../../external/Lucene.Net/src/core/Index/FieldsReader.cs +../../../external/Lucene.Net/src/core/Index/FieldsWriter.cs +../../../external/Lucene.Net/src/core/Index/FilterIndexReader.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsDocsConsumer.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsDocsWriter.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsFieldsConsumer.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsFieldsWriter.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsPositionsConsumer.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsPositionsWriter.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsTermsConsumer.cs +../../../external/Lucene.Net/src/core/Index/FormatPostingsTermsWriter.cs +../../../external/Lucene.Net/src/core/Index/FreqProxFieldMergeState.cs +../../../external/Lucene.Net/src/core/Index/FreqProxTermsWriter.cs +../../../external/Lucene.Net/src/core/Index/FreqProxTermsWriterPerField.cs +../../../external/Lucene.Net/src/core/Index/FreqProxTermsWriterPerThread.cs +../../../external/Lucene.Net/src/core/Index/IndexCommit.cs +../../../external/Lucene.Net/src/core/Index/IndexDeletionPolicy.cs +../../../external/Lucene.Net/src/core/Index/IndexFileDeleter.cs +../../../external/Lucene.Net/src/core/Index/IndexFileNameFilter.cs +../../../external/Lucene.Net/src/core/Index/IndexFileNames.cs +../../../external/Lucene.Net/src/core/Index/IndexReader.cs +../../../external/Lucene.Net/src/core/Index/IndexWriter.cs +../../../external/Lucene.Net/src/core/Index/IntBlockPool.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocConsumer.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocConsumerPerField.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocConsumerPerThread.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocEndConsumer.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocEndConsumerPerField.cs +../../../external/Lucene.Net/src/core/Index/InvertedDocEndConsumerPerThread.cs +../../../external/Lucene.Net/src/core/Index/KeepOnlyLastCommitDeletionPolicy.cs +../../../external/Lucene.Net/src/core/Index/LogByteSizeMergePolicy.cs +../../../external/Lucene.Net/src/core/Index/LogDocMergePolicy.cs +../../../external/Lucene.Net/src/core/Index/LogMergePolicy.cs +../../../external/Lucene.Net/src/core/Index/MergeDocIDRemapper.cs +../../../external/Lucene.Net/src/core/Index/MergePolicy.cs +../../../external/Lucene.Net/src/core/Index/MergeScheduler.cs +../../../external/Lucene.Net/src/core/Index/MultiLevelSkipListReader.cs +../../../external/Lucene.Net/src/core/Index/MultiLevelSkipListWriter.cs +../../../external/Lucene.Net/src/core/Index/MultipleTermPositions.cs +../../../external/Lucene.Net/src/core/Index/MultiReader.cs +../../../external/Lucene.Net/src/core/Index/NormsWriter.cs +../../../external/Lucene.Net/src/core/Index/NormsWriterPerField.cs +../../../external/Lucene.Net/src/core/Index/NormsWriterPerThread.cs +../../../external/Lucene.Net/src/core/Index/ParallelReader.cs +../../../external/Lucene.Net/src/core/Index/Payload.cs +../../../external/Lucene.Net/src/core/Index/PositionBasedTermVectorMapper.cs +../../../external/Lucene.Net/src/core/Index/RawPostingList.cs +../../../external/Lucene.Net/src/core/Index/ReadOnlyDirectoryReader.cs +../../../external/Lucene.Net/src/core/Index/ReadOnlySegmentReader.cs +../../../external/Lucene.Net/src/core/Index/ReusableStringReader.cs +../../../external/Lucene.Net/src/core/Index/SegmentInfo.cs +../../../external/Lucene.Net/src/core/Index/SegmentInfos.cs +../../../external/Lucene.Net/src/core/Index/SegmentMergeInfo.cs +../../../external/Lucene.Net/src/core/Index/SegmentMergeQueue.cs +../../../external/Lucene.Net/src/core/Index/SegmentMerger.cs +../../../external/Lucene.Net/src/core/Index/SegmentReader.cs +../../../external/Lucene.Net/src/core/Index/SegmentTermDocs.cs +../../../external/Lucene.Net/src/core/Index/SegmentTermEnum.cs +../../../external/Lucene.Net/src/core/Index/SegmentTermPositions.cs +../../../external/Lucene.Net/src/core/Index/SegmentTermPositionVector.cs +../../../external/Lucene.Net/src/core/Index/SegmentTermVector.cs +../../../external/Lucene.Net/src/core/Index/SegmentWriteState.cs +../../../external/Lucene.Net/src/core/Index/SerialMergeScheduler.cs +../../../external/Lucene.Net/src/core/Index/SnapshotDeletionPolicy.cs +../../../external/Lucene.Net/src/core/Index/SortedTermVectorMapper.cs +../../../external/Lucene.Net/src/core/Index/StaleReaderException.cs +../../../external/Lucene.Net/src/core/Index/StoredFieldsWriter.cs +../../../external/Lucene.Net/src/core/Index/StoredFieldsWriterPerThread.cs +../../../external/Lucene.Net/src/core/Index/Term.cs +../../../external/Lucene.Net/src/core/Index/TermBuffer.cs +../../../external/Lucene.Net/src/core/Index/TermDocs.cs +../../../external/Lucene.Net/src/core/Index/TermEnum.cs +../../../external/Lucene.Net/src/core/Index/TermFreqVector.cs +../../../external/Lucene.Net/src/core/Index/TermInfo.cs +../../../external/Lucene.Net/src/core/Index/TermInfosReader.cs +../../../external/Lucene.Net/src/core/Index/TermInfosWriter.cs +../../../external/Lucene.Net/src/core/Index/TermPositions.cs +../../../external/Lucene.Net/src/core/Index/TermPositionVector.cs +../../../external/Lucene.Net/src/core/Index/TermsHash.cs +../../../external/Lucene.Net/src/core/Index/TermsHashConsumer.cs +../../../external/Lucene.Net/src/core/Index/TermsHashConsumerPerField.cs +../../../external/Lucene.Net/src/core/Index/TermsHashConsumerPerThread.cs +../../../external/Lucene.Net/src/core/Index/TermsHashPerField.cs +../../../external/Lucene.Net/src/core/Index/TermsHashPerThread.cs +../../../external/Lucene.Net/src/core/Index/TermVectorEntry.cs +../../../external/Lucene.Net/src/core/Index/TermVectorEntryFreqSortedComparator.cs +../../../external/Lucene.Net/src/core/Index/TermVectorMapper.cs +../../../external/Lucene.Net/src/core/Index/TermVectorOffsetInfo.cs +../../../external/Lucene.Net/src/core/Index/TermVectorsReader.cs +../../../external/Lucene.Net/src/core/Index/TermVectorsTermsWriter.cs +../../../external/Lucene.Net/src/core/Index/TermVectorsTermsWriterPerField.cs +../../../external/Lucene.Net/src/core/Index/TermVectorsTermsWriterPerThread.cs +../../../external/Lucene.Net/src/core/Index/TermVectorsWriter.cs +../../../external/Lucene.Net/src/core/LucenePackage.cs +../../../external/Lucene.Net/src/core/LZOCompressor.cs +../../../external/Lucene.Net/src/core/Messages/INLSException.cs +../../../external/Lucene.Net/src/core/Messages/Message.cs +../../../external/Lucene.Net/src/core/Messages/MessageImpl.cs +../../../external/Lucene.Net/src/core/Messages/NLS.cs +../../../external/Lucene.Net/src/core/QueryParser/CharStream.cs +../../../external/Lucene.Net/src/core/QueryParser/FastCharStream.cs +../../../external/Lucene.Net/src/core/QueryParser/MultiFieldQueryParser.cs +../../../external/Lucene.Net/src/core/QueryParser/ParseException.cs +../../../external/Lucene.Net/src/core/QueryParser/QueryParser.cs +../../../external/Lucene.Net/src/core/QueryParser/QueryParserConstants.cs +../../../external/Lucene.Net/src/core/QueryParser/QueryParserTokenManager.cs +../../../external/Lucene.Net/src/core/QueryParser/Token.cs +../../../external/Lucene.Net/src/core/QueryParser/TokenMgrError.cs +../../../external/Lucene.Net/src/core/Search/BooleanClause.cs +../../../external/Lucene.Net/src/core/Search/BooleanQuery.cs +../../../external/Lucene.Net/src/core/Search/BooleanScorer.cs +../../../external/Lucene.Net/src/core/Search/BooleanScorer2.cs +../../../external/Lucene.Net/src/core/Search/CachingSpanFilter.cs +../../../external/Lucene.Net/src/core/Search/CachingWrapperFilter.cs +../../../external/Lucene.Net/src/core/Search/Collector.cs +../../../external/Lucene.Net/src/core/Search/ComplexExplanation.cs +../../../external/Lucene.Net/src/core/Search/ConjunctionScorer.cs +../../../external/Lucene.Net/src/core/Search/ConstantScoreQuery.cs +../../../external/Lucene.Net/src/core/Search/DefaultSimilarity.cs +../../../external/Lucene.Net/src/core/Search/DisjunctionMaxQuery.cs +../../../external/Lucene.Net/src/core/Search/DisjunctionMaxScorer.cs +../../../external/Lucene.Net/src/core/Search/DisjunctionSumScorer.cs +../../../external/Lucene.Net/src/core/Search/DocIdSet.cs +../../../external/Lucene.Net/src/core/Search/DocIdSetIterator.cs +../../../external/Lucene.Net/src/core/Search/ExactPhraseScorer.cs +../../../external/Lucene.Net/src/core/Search/Explanation.cs +../../../external/Lucene.Net/src/core/Search/FieldCache.cs +../../../external/Lucene.Net/src/core/Search/FieldCacheImpl.cs +../../../external/Lucene.Net/src/core/Search/FieldCacheRangeFilter.cs +../../../external/Lucene.Net/src/core/Search/FieldCacheTermsFilter.cs +../../../external/Lucene.Net/src/core/Search/FieldComparator.cs +../../../external/Lucene.Net/src/core/Search/FieldComparatorSource.cs +../../../external/Lucene.Net/src/core/Search/FieldDoc.cs +../../../external/Lucene.Net/src/core/Search/FieldDocSortedHitQueue.cs +../../../external/Lucene.Net/src/core/Search/FieldValueHitQueue.cs +../../../external/Lucene.Net/src/core/Search/Filter.cs +../../../external/Lucene.Net/src/core/Search/FilteredDocIdSet.cs +../../../external/Lucene.Net/src/core/Search/FilteredDocIdSetIterator.cs +../../../external/Lucene.Net/src/core/Search/FilteredQuery.cs +../../../external/Lucene.Net/src/core/Search/FilteredTermEnum.cs +../../../external/Lucene.Net/src/core/Search/FilterManager.cs +../../../external/Lucene.Net/src/core/Search/Function/ByteFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/CustomScoreProvider.cs +../../../external/Lucene.Net/src/core/Search/Function/CustomScoreQuery.cs +../../../external/Lucene.Net/src/core/Search/Function/DocValues.cs +../../../external/Lucene.Net/src/core/Search/Function/FieldCacheSource.cs +../../../external/Lucene.Net/src/core/Search/Function/FieldScoreQuery.cs +../../../external/Lucene.Net/src/core/Search/Function/FloatFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/IntFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/OrdFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/ReverseOrdFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/ShortFieldSource.cs +../../../external/Lucene.Net/src/core/Search/Function/ValueSource.cs +../../../external/Lucene.Net/src/core/Search/Function/ValueSourceQuery.cs +../../../external/Lucene.Net/src/core/Search/FuzzyQuery.cs +../../../external/Lucene.Net/src/core/Search/FuzzyTermEnum.cs +../../../external/Lucene.Net/src/core/Search/HitQueue.cs +../../../external/Lucene.Net/src/core/Search/IndexSearcher.cs +../../../external/Lucene.Net/src/core/Search/MatchAllDocsQuery.cs +../../../external/Lucene.Net/src/core/Search/MultiPhraseQuery.cs +../../../external/Lucene.Net/src/core/Search/MultiSearcher.cs +../../../external/Lucene.Net/src/core/Search/MultiTermQuery.cs +../../../external/Lucene.Net/src/core/Search/MultiTermQueryWrapperFilter.cs +../../../external/Lucene.Net/src/core/Search/NumericRangeFilter.cs +../../../external/Lucene.Net/src/core/Search/NumericRangeQuery.cs +../../../external/Lucene.Net/src/core/Search/ParallelMultiSearcher.cs +../../../external/Lucene.Net/src/core/Search/Payloads/AveragePayloadFunction.cs +../../../external/Lucene.Net/src/core/Search/Payloads/MaxPayloadFunction.cs +../../../external/Lucene.Net/src/core/Search/Payloads/MinPayloadFunction.cs +../../../external/Lucene.Net/src/core/Search/Payloads/PayloadFunction.cs +../../../external/Lucene.Net/src/core/Search/Payloads/PayloadNearQuery.cs +../../../external/Lucene.Net/src/core/Search/Payloads/PayloadSpanUtil.cs +../../../external/Lucene.Net/src/core/Search/Payloads/PayloadTermQuery.cs +../../../external/Lucene.Net/src/core/Search/PhrasePositions.cs +../../../external/Lucene.Net/src/core/Search/PhraseQuery.cs +../../../external/Lucene.Net/src/core/Search/PhraseQueue.cs +../../../external/Lucene.Net/src/core/Search/PhraseScorer.cs +../../../external/Lucene.Net/src/core/Search/PositiveScoresOnlyCollector.cs +../../../external/Lucene.Net/src/core/Search/PrefixFilter.cs +../../../external/Lucene.Net/src/core/Search/PrefixQuery.cs +../../../external/Lucene.Net/src/core/Search/PrefixTermEnum.cs +../../../external/Lucene.Net/src/core/Search/Query.cs +../../../external/Lucene.Net/src/core/Search/QueryTermVector.cs +../../../external/Lucene.Net/src/core/Search/QueryWrapperFilter.cs +../../../external/Lucene.Net/src/core/Search/ReqExclScorer.cs +../../../external/Lucene.Net/src/core/Search/ReqOptSumScorer.cs +../../../external/Lucene.Net/src/core/Search/ScoreCachingWrappingScorer.cs +../../../external/Lucene.Net/src/core/Search/ScoreDoc.cs +../../../external/Lucene.Net/src/core/Search/Scorer.cs +../../../external/Lucene.Net/src/core/Search/Searchable.cs +../../../external/Lucene.Net/src/core/Search/Searcher.cs +../../../external/Lucene.Net/src/core/Search/Similarity.cs +../../../external/Lucene.Net/src/core/Search/SimilarityDelegator.cs +../../../external/Lucene.Net/src/core/Search/SingleTermEnum.cs +../../../external/Lucene.Net/src/core/Search/SloppyPhraseScorer.cs +../../../external/Lucene.Net/src/core/Search/Sort.cs +../../../external/Lucene.Net/src/core/Search/SortField.cs +../../../external/Lucene.Net/src/core/Search/SpanFilter.cs +../../../external/Lucene.Net/src/core/Search/SpanFilterResult.cs +../../../external/Lucene.Net/src/core/Search/SpanQueryFilter.cs +../../../external/Lucene.Net/src/core/Search/Spans/FieldMaskingSpanQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/NearSpansOrdered.cs +../../../external/Lucene.Net/src/core/Search/Spans/NearSpansUnordered.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanFirstQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanNearQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanNotQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanOrQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/Spans.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanScorer.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanTermQuery.cs +../../../external/Lucene.Net/src/core/Search/Spans/SpanWeight.cs +../../../external/Lucene.Net/src/core/Search/Spans/TermSpans.cs +../../../external/Lucene.Net/src/core/Search/TermQuery.cs +../../../external/Lucene.Net/src/core/Search/TermRangeFilter.cs +../../../external/Lucene.Net/src/core/Search/TermRangeQuery.cs +../../../external/Lucene.Net/src/core/Search/TermRangeTermEnum.cs +../../../external/Lucene.Net/src/core/Search/TermScorer.cs +../../../external/Lucene.Net/src/core/Search/TimeLimitingCollector.cs +../../../external/Lucene.Net/src/core/Search/TopDocs.cs +../../../external/Lucene.Net/src/core/Search/TopDocsCollector.cs +../../../external/Lucene.Net/src/core/Search/TopFieldCollector.cs +../../../external/Lucene.Net/src/core/Search/TopFieldDocs.cs +../../../external/Lucene.Net/src/core/Search/TopScoreDocCollector.cs +../../../external/Lucene.Net/src/core/Search/Weight.cs +../../../external/Lucene.Net/src/core/Search/WildcardQuery.cs +../../../external/Lucene.Net/src/core/Search/WildcardTermEnum.cs +../../../external/Lucene.Net/src/core/Store/AlreadyClosedException.cs +../../../external/Lucene.Net/src/core/Store/BufferedIndexInput.cs +../../../external/Lucene.Net/src/core/Store/BufferedIndexOutput.cs +../../../external/Lucene.Net/src/core/Store/CheckSumIndexInput.cs +../../../external/Lucene.Net/src/core/Store/CheckSumIndexOutput.cs +../../../external/Lucene.Net/src/core/Store/Directory.cs +../../../external/Lucene.Net/src/core/Store/FileSwitchDirectory.cs +../../../external/Lucene.Net/src/core/Store/FSDirectory.cs +../../../external/Lucene.Net/src/core/Store/FSLockFactory.cs +../../../external/Lucene.Net/src/core/Store/IndexInput.cs +../../../external/Lucene.Net/src/core/Store/IndexOutput.cs +../../../external/Lucene.Net/src/core/Store/Lock.cs +../../../external/Lucene.Net/src/core/Store/LockFactory.cs +../../../external/Lucene.Net/src/core/Store/LockObtainFailedException.cs +../../../external/Lucene.Net/src/core/Store/LockReleaseFailedException.cs +../../../external/Lucene.Net/src/core/Store/LockStressTest.cs +../../../external/Lucene.Net/src/core/Store/LockVerifyServer.cs +../../../external/Lucene.Net/src/core/Store/MMapDirectory.cs +../../../external/Lucene.Net/src/core/Store/NativeFSLockFactory.cs +../../../external/Lucene.Net/src/core/Store/NIOFSDirectory.cs +../../../external/Lucene.Net/src/core/Store/NoLockFactory.cs +../../../external/Lucene.Net/src/core/Store/NoSuchDirectoryException.cs +../../../external/Lucene.Net/src/core/Store/RAMDirectory.cs +../../../external/Lucene.Net/src/core/Store/RAMFile.cs +../../../external/Lucene.Net/src/core/Store/RAMInputStream.cs +../../../external/Lucene.Net/src/core/Store/RAMOutputStream.cs +../../../external/Lucene.Net/src/core/Store/SimpleFSDirectory.cs +../../../external/Lucene.Net/src/core/Store/SimpleFSLockFactory.cs +../../../external/Lucene.Net/src/core/Store/SingleInstanceLockFactory.cs +../../../external/Lucene.Net/src/core/Store/VerifyingLockFactory.cs +../../../external/Lucene.Net/src/core/Support/AppSettings.cs +../../../external/Lucene.Net/src/core/Support/AttributeImplItem.cs +../../../external/Lucene.Net/src/core/Support/BitSetSupport.cs +../../../external/Lucene.Net/src/core/Support/BuildType.cs +../../../external/Lucene.Net/src/core/Support/Character.cs +../../../external/Lucene.Net/src/core/Support/CloseableThreadLocalProfiler.cs +../../../external/Lucene.Net/src/core/Support/CollectionsHelper.cs +../../../external/Lucene.Net/src/core/Support/Compare.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/ConcurrentDictionary.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/Func.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/ISet.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/SetFactory.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/SortedSet.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/ThreadLocal.cs +../../../external/Lucene.Net/src/core/Support/Compatibility/WrappedHashSet.cs +../../../external/Lucene.Net/src/core/Support/CRC32.cs +../../../external/Lucene.Net/src/core/Support/Cryptography.cs +../../../external/Lucene.Net/src/core/Support/Deflater.cs +../../../external/Lucene.Net/src/core/Support/Double.cs +../../../external/Lucene.Net/src/core/Support/EquatableList.cs +../../../external/Lucene.Net/src/core/Support/FileSupport.cs +../../../external/Lucene.Net/src/core/Support/GeneralKeyedCollection.cs +../../../external/Lucene.Net/src/core/Support/HashMap.cs +../../../external/Lucene.Net/src/core/Support/IChecksum.cs +../../../external/Lucene.Net/src/core/Support/Inflater.cs +../../../external/Lucene.Net/src/core/Support/IThreadRunnable.cs +../../../external/Lucene.Net/src/core/Support/Number.cs +../../../external/Lucene.Net/src/core/Support/OS.cs +../../../external/Lucene.Net/src/core/Support/SharpZipLib.cs +../../../external/Lucene.Net/src/core/Support/Single.cs +../../../external/Lucene.Net/src/core/Support/TextSupport.cs +../../../external/Lucene.Net/src/core/Support/ThreadClass.cs +../../../external/Lucene.Net/src/core/Support/ThreadLock.cs +../../../external/Lucene.Net/src/core/Support/WeakDictionary.cs +../../../external/Lucene.Net/src/core/Util/ArrayUtil.cs +../../../external/Lucene.Net/src/core/Util/Attribute.cs +../../../external/Lucene.Net/src/core/Util/AttributeSource.cs +../../../external/Lucene.Net/src/core/Util/AverageGuessMemoryModel.cs +../../../external/Lucene.Net/src/core/Util/BitUtil.cs +../../../external/Lucene.Net/src/core/Util/BitVector.cs +../../../external/Lucene.Net/src/core/Util/Cache/Cache.cs +../../../external/Lucene.Net/src/core/Util/Cache/SimpleLRUCache.cs +../../../external/Lucene.Net/src/core/Util/Cache/SimpleMapCache.cs +../../../external/Lucene.Net/src/core/Util/CloseableThreadLocal.cs +../../../external/Lucene.Net/src/core/Util/Constants.cs +../../../external/Lucene.Net/src/core/Util/DocIdBitSet.cs +../../../external/Lucene.Net/src/core/Util/FieldCacheSanityChecker.cs +../../../external/Lucene.Net/src/core/Util/IAttribute.cs +../../../external/Lucene.Net/src/core/Util/IdentityDictionary.cs +../../../external/Lucene.Net/src/core/Util/IndexableBinaryStringTools.cs +../../../external/Lucene.Net/src/core/Util/MapOfSets.cs +../../../external/Lucene.Net/src/core/Util/MemoryModel.cs +../../../external/Lucene.Net/src/core/Util/NumericUtils.cs +../../../external/Lucene.Net/src/core/Util/OpenBitSet.cs +../../../external/Lucene.Net/src/core/Util/OpenBitSetDISI.cs +../../../external/Lucene.Net/src/core/Util/OpenBitSetIterator.cs +../../../external/Lucene.Net/src/core/Util/PriorityQueue.cs +../../../external/Lucene.Net/src/core/Util/RamUsageEstimator.cs +../../../external/Lucene.Net/src/core/Util/ReaderUtil.cs +../../../external/Lucene.Net/src/core/Util/ScorerDocQueue.cs +../../../external/Lucene.Net/src/core/Util/SimpleStringInterner.cs +../../../external/Lucene.Net/src/core/Util/SmallFloat.cs +../../../external/Lucene.Net/src/core/Util/SortedVIntList.cs +../../../external/Lucene.Net/src/core/Util/SorterTemplate.cs +../../../external/Lucene.Net/src/core/Util/StringHelper.cs +../../../external/Lucene.Net/src/core/Util/StringInterner.cs +../../../external/Lucene.Net/src/core/Util/ToStringUtils.cs +../../../external/Lucene.Net/src/core/Util/UnicodeUtil.cs +../../../external/Lucene.Net/src/core/Util/Version.cs diff --git a/mcs/tools/monkeydoc/monkeydoc_test.dll.sources b/mcs/tools/monkeydoc/monkeydoc_test.dll.sources new file mode 100644 index 00000000000..d57ee1e15db --- /dev/null +++ b/mcs/tools/monkeydoc/monkeydoc_test.dll.sources @@ -0,0 +1,2 @@ +Monkeydoc/HelpSourceTests.cs +Monkeydoc.Ecma/EcmaUrlTests.cs \ No newline at end of file diff --git a/mcs/tools/monodoc/Makefile b/mcs/tools/monodoc/Makefile index 700a975405b..d4e38ad059b 100644 --- a/mcs/tools/monodoc/Makefile +++ b/mcs/tools/monodoc/Makefile @@ -158,3 +158,10 @@ clean-local: cleanup cleanup: -rm -f Test/man-provider-test.exe* +API_SERVER = root@api.xamarin.com + +push: + make PROFILE=net_4_0 MCS_FLAGS=/debug + scp "../../class/lib/net_4_0/monodoc.dll*" $(API_SERVER):/srv/monodoc/ + ssh $(API_SERVER) "/etc/init.d/apache2 reload" + ssh $(API_SERVER) "echo On `date -u +"%F %R"` UTC by `whoami` based on revision: `git log -n1 --oneline` >> /srv/monodoc/Changelog" diff --git a/mcs/tools/monodoc/Monodoc/ecma-provider.cs b/mcs/tools/monodoc/Monodoc/ecma-provider.cs index 0033472a8ad..e0e52691b17 100644 --- a/mcs/tools/monodoc/Monodoc/ecma-provider.cs +++ b/mcs/tools/monodoc/Monodoc/ecma-provider.cs @@ -845,7 +845,7 @@ public class EcmaHelpSource : HelpSource { if ((membername == "op_Implicit" || membername == "op_Explicit") && argtypes.Length == 2) { isoperator = true; - membername = "Conversion"; + membername = membername.EndsWith ("Implicit") ? "ImplicitConversion" : "ExplicitConversion"; member = argtypes[0] + " to " + argtypes[1]; } else if (membername.StartsWith("op_")) { isoperator = true; @@ -991,7 +991,7 @@ public class EcmaHelpSource : HelpSource { // conversion operators: overloading based on parameter and return type [ECMA-335 §10.3.3] case "op_Implicit": // static implicit operator R (T) case "op_Explicit": // static explicit operator R (T) - nicename = "Conversion"; + nicename = name.EndsWith ("Implicit") ? "ImplicitConversion" : "ExplicitConversion"; string arg = n.SelectSingleNode("Parameters/Parameter/@Type").InnerText; string ret = n.SelectSingleNode("ReturnValue/ReturnType").InnerText; sig = EcmaDoc.ConvertCTSName(arg) + " to " + EcmaDoc.ConvertCTSName(ret); @@ -2183,8 +2183,8 @@ public class EcmaHelpSource : HelpSource { .Concat (ncnodes.Where (n => n.Nodes.Count > 0).SelectMany (n => n.Nodes.Cast ())); } else if (c.Caption == "Operators") { ncnodes = ncnodes - .Where (n => n.Caption != "Conversion") - .Concat (ncnodes.Where (n => n.Caption == "Conversion").SelectMany (n => n.Nodes.Cast ())); + .Where (n => !n.Caption.EndsWith ("Conversion")) + .Concat (ncnodes.Where (n => n.Caption.EndsWith ("Conversion")).SelectMany (n => n.Nodes.Cast ())); } foreach (Node nc in ncnodes) { //xpath to the docs xml node diff --git a/mcs/tools/monodoc/Monodoc/provider.cs b/mcs/tools/monodoc/Monodoc/provider.cs index d79ce079e19..180ae0d1f4e 100644 --- a/mcs/tools/monodoc/Monodoc/provider.cs +++ b/mcs/tools/monodoc/Monodoc/provider.cs @@ -132,7 +132,6 @@ public class Node : IComparable { Node parent; protected ArrayList nodes; protected internal int position; - string compare_key; static ArrayList empty = ArrayList.ReadOnly(new ArrayList(0)); @@ -394,19 +393,25 @@ public class Node : IComparable { LoadNode (); if (other.position < 0) other.LoadNode (); - if (compare_key == null || other.compare_key == null) { - Regex digits = new Regex (@"([\d]+)|([^\d]+)"); - MatchEvaluator eval = delegate (Match m) { - return (m.Value.Length > 0 && char.IsDigit (m.Value [0])) - ? m.Value.PadLeft (System.Math.Max (caption.Length, other.caption.Length)) - : m.Value; - }; - if (compare_key == null) - compare_key = digits.Replace (caption, eval); - if (other.compare_key == null) - other.compare_key = digits.Replace (other.caption, eval); - } - return compare_key.CompareTo (other.compare_key); + + var cap1 = caption; + var cap2 = other.caption; + + /* Some node (notably from ecmaspec) have number prepended to them + * which we need to sort better by padding them to the same number + * of digits + */ + if (char.IsDigit (cap1[0]) && char.IsDigit (cap2[0])) { + int c1 = cap1.TakeWhile (char.IsDigit).Count (); + int c2 = cap2.TakeWhile (char.IsDigit).Count (); + + if (c1 != c2) { + cap1 = cap1.PadLeft (cap1.Length + Math.Max (0, c2 - c1), '0'); + cap2 = cap2.PadLeft (cap2.Length + Math.Max (0, c1 - c2), '0'); + } + } + + return string.Compare (cap1, cap2, StringComparison.OrdinalIgnoreCase); } } diff --git a/mcs/tools/tuner/Mono.Tuner/CustomizeActions.cs b/mcs/tools/tuner/Mono.Tuner/CustomizeActions.cs index 3f0da1895d0..59077e04176 100644 --- a/mcs/tools/tuner/Mono.Tuner/CustomizeActions.cs +++ b/mcs/tools/tuner/Mono.Tuner/CustomizeActions.cs @@ -47,6 +47,12 @@ namespace Mono.Tuner { bool IsSkipped (AssemblyDefinition assembly) { + if (assembly.HasCustomAttributes) { + foreach (var ca in assembly.CustomAttributes) { + if (ca.AttributeType.Name == "PreserveAttribute") + return true; + } + } return skipped_assemblies.Contains (assembly.Name.Name); } diff --git a/mono/Makefile.am b/mono/Makefile.am index 2d796f1c480..0345c9ddd82 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -1,5 +1,30 @@ if CROSS_COMPILING -SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis +SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis profiler +else +if INSTALL_MONOTOUCH +SUBDIRS = utils io-layer metadata arch mini profiler + +monotouch-do-build: + @list='$(SUBDIRS)'; for subdir in $$list; do \ + case "x$$subdir" in \ + xmetadata ) target="monotouch-do-build" ;; \ + xmini ) target="monotouch-do-build" ;; \ + * ) target="all" ;; \ + esac; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ + done; + +monotouch-do-clean: + @list='$(SUBDIRS)'; for subdir in $$list; do \ + case "x$$subdir" in \ + xmetadata ) target="monotouch-do-clean" ;; \ + xmini ) target="monotouch-do-clean" ;; \ + * ) target="clean" ;; \ + esac; \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ + done; else if MOONLIGHT SUBDIRS = arch utils io-layer metadata mini @@ -30,4 +55,5 @@ else SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests benchmark profiler endif endif +endif DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests benchmark profiler diff --git a/mono/arch/arm/arm-vfp-codegen.h b/mono/arch/arm/arm-vfp-codegen.h index d0fdb29b8e7..c4c5e3e2252 100644 --- a/mono/arch/arm/arm-vfp-codegen.h +++ b/mono/arch/arm/arm-vfp-codegen.h @@ -172,7 +172,7 @@ enum { #define ARM_FSTMD(p,first_reg,nregs,base) \ ARM_FSTMD_COND(p,first_reg,nregs,base,ARMCOND_AL) -#include "arm_vfpmacros.h" +#include /* coprocessor register transfer */ #define ARM_FMSR(p,freg,reg) \ diff --git a/mono/dis/Makefile.am b/mono/dis/Makefile.am index 477af4641a7..fd581ff5514 100644 --- a/mono/dis/Makefile.am +++ b/mono/dis/Makefile.am @@ -24,10 +24,14 @@ endif if DISABLE_EXECUTABLES bin_PROGRAMS = else +if DISABLE_LIBRARIES +bin_PROGRAMS = +else if SUPPORT_BOEHM bin_PROGRAMS = monodis endif endif +endif noinst_LIBRARIES = libmonodis.a diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index 586b54715db..ab0f1195cf0 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -33,6 +33,7 @@ /* sys/resource.h (for rusage) is required when using osx 10.3 (but not 10.4) */ #ifdef __APPLE__ +#include #include #ifdef HAVE_LIBPROC_H /* proc_name */ @@ -2136,7 +2137,7 @@ static gchar *get_process_name_from_proc (pid_t pid) } g_free (filename); #elif defined(PLATFORM_MACOSX) -#if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) && !defined (__mono_ppc__) && !defined(__arm__) +#if !defined (__mono_ppc__) && defined (TARGET_OSX) /* No proc name on OSX < 10.5 nor ppc nor iOS */ memset (buf, '\0', sizeof(buf)); proc_name (pid, buf, sizeof(buf)); diff --git a/mono/io-layer/wthreads.c b/mono/io-layer/wthreads.c index 41f271ec4cf..0a422356378 100644 --- a/mono/io-layer/wthreads.c +++ b/mono/io-layer/wthreads.c @@ -927,7 +927,7 @@ guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer handle, return (0); } - g_assert (thread_handle->id == GetCurrentThreadId ()); + g_assert (thread_handle->id == (pthread_t)GetCurrentThreadId ()); /* No locking/memory barriers are needed here */ thread_handle->has_apc = TRUE; return(1); diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index e026bdde580..6f04f32df6c 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -39,16 +39,24 @@ endif # convenience lib, so we have to do it ourselves # if SUPPORT_SGEN +if DISABLE_EXECUTABLES +shared_sgen_libraries = libmonoruntimesgen.la +else if SHARED_MONO shared_sgen_libraries = libmonoruntimesgen.la endif +endif sgen_libraries = $(shared_sgen_libraries) libmonoruntimesgen-static.la endif if SUPPORT_BOEHM +if DISABLE_EXECUTABLES +shared_boehm_libraries = libmonoruntime.la +else if SHARED_MONO shared_boehm_libraries = libmonoruntime.la endif +endif boehm_libraries = $(shared_boehm_libraries) libmonoruntime-static.la endif @@ -257,7 +265,7 @@ sgen_sources = \ sgen-stw.c \ sgen-fin-weak-hash.c -libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(sgen_sources) $(boehm_sources) +libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(boehm_sources) libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES) if MOONLIGHT @@ -269,14 +277,14 @@ libmonoruntimemoon_la_CFLAGS = $(MOONLIGHT_DEFINES) $(SGEN_DEFINES) endif endif -libmonoruntimesgen_la_SOURCES = $(libmonoruntime_la_SOURCES) +libmonoruntimesgen_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(sgen_sources) libmonoruntimesgen_la_CFLAGS = $(SGEN_DEFINES) libmonoruntime_static_la_SOURCES = $(libmonoruntime_la_SOURCES) libmonoruntime_static_la_LDFLAGS = -static libmonoruntime_static_la_CFLAGS = $(BOEHM_DEFINES) -libmonoruntimesgen_static_la_SOURCES = $(libmonoruntime_la_SOURCES) +libmonoruntimesgen_static_la_SOURCES = $(libmonoruntimesgen_la_SOURCES) libmonoruntimesgen_static_la_LDFLAGS = -static libmonoruntimesgen_static_la_CFLAGS = $(SGEN_DEFINES) diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 2907af6d492..04ce7e331a5 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -75,7 +75,7 @@ * Changes which are already detected at runtime, like the addition * of icalls, do not require an increment. */ -#define MONO_CORLIB_VERSION 107 +#define MONO_CORLIB_VERSION 108 typedef struct { diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c index 819cf392bfa..7f49b4ce50c 100644 --- a/mono/metadata/assembly.c +++ b/mono/metadata/assembly.c @@ -114,6 +114,7 @@ static const AssemblyVersionMap framework_assemblies [] = { {"System.Management", 0}, {"System.Messaging", 0}, {"System.Runtime.Remoting", 0}, + {"System.Runtime.Serialization", 2}, {"System.Runtime.Serialization.Formatters.Soap", 0}, {"System.Security", 0}, {"System.ServiceProcess", 0}, diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c index 0defba28ec3..b7a5c79e5d9 100644 --- a/mono/metadata/boehm-gc.c +++ b/mono/metadata/boehm-gc.c @@ -208,7 +208,9 @@ mono_gc_collect (int generation) { MONO_GC_BEGIN (generation); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_induced++; +#endif GC_gcollect (); MONO_GC_END (generation); @@ -410,11 +412,14 @@ on_gc_notification (GCEventType event) mono_thread_info_suspend_unlock (); if (e == MONO_GC_EVENT_START) { +#ifndef DISABLE_PERFCOUNTERS if (mono_perfcounters) mono_perfcounters->gc_collections0++; +#endif gc_stats.major_gc_count ++; gc_start_time = mono_100ns_ticks (); } else if (e == MONO_GC_EVENT_END) { +#ifndef DISABLE_PERFCOUNTERS if (mono_perfcounters) { guint64 heap_size = GC_get_heap_size (); guint64 used_size = heap_size - GC_get_free_bytes (); @@ -423,6 +428,7 @@ on_gc_notification (GCEventType event) mono_perfcounters->gc_reserved_bytes = heap_size; mono_perfcounters->gc_gen0size = heap_size; } +#endif gc_stats.major_gc_time_usecs += (mono_100ns_ticks () - gc_start_time) / 10; mono_trace_message (MONO_TRACE_GC, "gc took %d usecs", (mono_100ns_ticks () - gc_start_time) / 10); } @@ -433,11 +439,13 @@ static void on_gc_heap_resize (size_t new_size) { guint64 heap_size = GC_get_heap_size (); +#ifndef DISABLE_PERFCOUNTERS if (mono_perfcounters) { mono_perfcounters->gc_committed_bytes = heap_size; mono_perfcounters->gc_reserved_bytes = heap_size; mono_perfcounters->gc_gen0size = heap_size; } +#endif mono_profiler_gc_heap_resize (new_size); } diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index f2dc35ea5de..bd74d47a72a 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1070,11 +1070,13 @@ typedef struct { MonoClass *internals_visible_class; MonoClass *generic_ilist_class; MonoClass *generic_nullable_class; +#ifndef DISABLE_COM MonoClass *variant_class; MonoClass *com_object_class; MonoClass *com_interop_proxy_class; MonoClass *iunknown_class; MonoClass *idispatch_class; +#endif MonoClass *safehandle_class; MonoClass *handleref_class; MonoClass *attribute_class; diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 933cd46c942..bba6afbff9c 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -5189,6 +5189,7 @@ mono_class_setup_mono_type (MonoClass *class) } +#ifndef DISABLE_COM /* * COM initialization (using mono_init_com_types) is delayed until needed. * However when a [ComImport] attribute is present on a type it will trigger @@ -5212,6 +5213,7 @@ init_com_from_comimport (MonoClass *class) /* FIXME : we should add an extra checks to ensure COM can be initialized properly before continuing */ mono_init_com_types (); } +#endif /*DISABLE_COM*/ /* * LOCKING: this assumes the loader lock is held @@ -5238,11 +5240,13 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent) if (!MONO_CLASS_IS_INTERFACE (class)) { /* Imported COM Objects always derive from __ComObject. */ +#ifndef DISABLE_COM if (MONO_CLASS_IS_IMPORT (class)) { init_com_from_comimport (class); if (parent == mono_defaults.object_class) parent = mono_defaults.com_object_class; } +#endif if (!parent) { /* set the parent to something useful and safe, but mark the type as broken */ parent = mono_defaults.object_class; @@ -5288,8 +5292,10 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent) /*class->enumtype = class->parent->enumtype; */ } else { /* initialize com types if COM interfaces are present */ +#ifndef DISABLE_COM if (MONO_CLASS_IS_IMPORT (class)) init_com_from_comimport (class); +#endif class->parent = NULL; } diff --git a/mono/metadata/cominterop.c b/mono/metadata/cominterop.c index f6adfcd1ce0..b13e311cbb6 100644 --- a/mono/metadata/cominterop.c +++ b/mono/metadata/cominterop.c @@ -35,6 +35,17 @@ #include #include +/* +Code shared between the DISABLE_COM and !DISABLE_COM +*/ +static void +register_icall (gpointer func, const char *name, const char *sigstr, gboolean save) +{ + MonoMethodSignature *sig = mono_create_icall_signature (sigstr); + + mono_register_jit_icall (func, name, sig, save); +} + #ifndef DISABLE_COM #define OPDEF(a,b,c,d,e,f,g,h,i,j) \ @@ -502,14 +513,6 @@ cominterop_type_from_handle (MonoType *handle) return mono_type_get_object (domain, handle); } -static void -register_icall (gpointer func, const char *name, const char *sigstr, gboolean save) -{ - MonoMethodSignature *sig = mono_create_icall_signature (sigstr); - - mono_register_jit_icall (func, name, sig, save); -} - void mono_cominterop_init (void) { @@ -3142,6 +3145,19 @@ void mono_marshal_safearray_free_indices (gpointer indices) void mono_cominterop_init (void) { + /*FIXME + + This icalls are used by the marshal code when doing PtrToStructure and StructureToPtr and pinvoke. + + If we leave them out and the FullAOT compiler finds the need to emit one of the above 3 wrappers it will + g_assert. + + The proper fix would be to emit warning, remove them from marshal.c when DISABLE_COM is used and + emit an exception in the generated IL. + */ + register_icall (mono_string_to_bstr, "mono_string_to_bstr", "ptr obj", FALSE); + register_icall (mono_string_from_bstr, "mono_string_from_bstr", "obj ptr", FALSE); + register_icall (mono_free_bstr, "mono_free_bstr", "void ptr", FALSE); } void diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index b9930878c3e..ccf2db538da 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -373,7 +373,6 @@ struct _MonoDomain { /* Used by threadpool.c */ MonoImage *system_image; - MonoImage *system_net_dll; MonoClass *corlib_asyncresult_class; MonoClass *socket_class; MonoClass *ad_unloaded_ex_class; diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index 66bebd13c88..5a17ff008f0 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -1227,8 +1227,10 @@ mono_domain_create (void) domain_id_alloc (domain); mono_appdomains_unlock (); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_appdomains++; mono_perfcounters->loader_total_appdomains++; +#endif mono_debug_domain_create (domain); @@ -1274,7 +1276,9 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * wapi_init (); #endif +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters_init (); +#endif mono_counters_register ("Max native code in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_size); mono_counters_register ("Max code space allocated in a domain", MONO_COUNTER_INT|MONO_COUNTER_JIT, &max_domain_code_alloc); @@ -1608,11 +1612,13 @@ mono_init_internal (const char *filename, const char *exe_filename, const char * mono_defaults.corlib, "System.Reflection", "CustomAttributeData"); /* these are initialized lazily when COM features are used */ +#ifndef DISABLE_COM mono_defaults.variant_class = NULL; mono_defaults.com_object_class = NULL; mono_defaults.com_interop_proxy_class = NULL; mono_defaults.iunknown_class = NULL; mono_defaults.idispatch_class = NULL; +#endif /* * Note that mono_defaults.generic_*_class is only non-NULL if we're @@ -1688,6 +1694,7 @@ mono_init_version (const char *domain_name, const char *version) return mono_init_internal (domain_name, NULL, version); } +#ifndef DISABLE_COM /** * mono_init_com_types: * @@ -1727,6 +1734,7 @@ mono_init_com_types (void) initialized = TRUE; } +#endif /*DISABLE_COM*/ /** * mono_cleanup: @@ -2050,7 +2058,9 @@ mono_domain_free (MonoDomain *domain, gboolean force) mono_mempool_invalidate (domain->mp); mono_code_manager_invalidate (domain->code_mp); #else +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes -= mono_mempool_get_allocated (domain->mp); +#endif mono_mempool_destroy (domain->mp); domain->mp = NULL; mono_code_manager_destroy (domain->code_mp); @@ -2094,7 +2104,9 @@ mono_domain_free (MonoDomain *domain, gboolean force) mono_gc_free_fixed (domain); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_appdomains--; +#endif if (domain == mono_root_domain) mono_root_domain = NULL; @@ -2138,7 +2150,9 @@ mono_domain_alloc (MonoDomain *domain, guint size) gpointer res; mono_domain_lock (domain); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += size; +#endif res = mono_mempool_alloc (domain->mp, size); mono_domain_unlock (domain); @@ -2156,7 +2170,9 @@ mono_domain_alloc0 (MonoDomain *domain, guint size) gpointer res; mono_domain_lock (domain); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += size; +#endif res = mono_mempool_alloc0 (domain->mp, size); mono_domain_unlock (domain); diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index f0b98183a5a..c6e01da6f6e 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -733,7 +733,9 @@ alloc_handle (HandleData *handles, MonoObject *obj, gboolean track) mono_gc_weak_link_add (&(handles->entries [slot]), obj, track); } +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_num_handles++; +#endif unlock_handles (handles); /*g_print ("allocated entry %d of type %d to object %p (in slot: %p)\n", slot, handles->type, obj, handles->entries [slot]);*/ res = (slot << 3) | (handles->type + 1); @@ -941,7 +943,9 @@ mono_gchandle_free (guint32 gchandle) } else { /* print a warning? */ } +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_num_handles--; +#endif /*g_print ("freed entry %d of type %d\n", slot, handles->type);*/ unlock_handles (handles); mono_profiler_gc_handle (MONO_PROFILER_GC_HANDLE_DESTROYED, handles->type, gchandle, NULL); @@ -1134,6 +1138,16 @@ finalizer_thread (gpointer unused) return 0; } +#ifndef LAZY_GC_THREAD_CREATION +static +#endif +void +mono_gc_init_finalizer_thread (void) +{ + gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, FALSE, 0); + ves_icall_System_Threading_Thread_SetName_internal (gc_thread, mono_string_new (mono_domain_get (), "Finalizer")); +} + void mono_gc_init (void) { @@ -1168,8 +1182,9 @@ mono_gc_init (void) MONO_SEM_INIT (&finalizer_sem, 0); #endif - gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, FALSE, 0); - ves_icall_System_Threading_Thread_SetName_internal (gc_thread, mono_string_new (mono_domain_get (), "Finalizer")); +#ifndef LAZY_GC_THREAD_CREATION + mono_gc_init_finalizer_thread (); +#endif } void diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 515b971212d..920385b4fee 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -177,10 +177,10 @@ ICALL(DEBUGR_3, "Log", ves_icall_System_Diagnostics_Debugger_Log) ICALL_TYPE(TRACEL, "System.Diagnostics.DefaultTraceListener", TRACEL_1) ICALL(TRACEL_1, "WriteWindowsDebugString", ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString) -#ifndef DISABLE_PROCESS_HANDLING ICALL_TYPE(FILEV, "System.Diagnostics.FileVersionInfo", FILEV_1) ICALL(FILEV_1, "GetVersionInfo_internal(string)", ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal) +#ifndef DISABLE_PROCESS_HANDLING ICALL_TYPE(PERFCTR, "System.Diagnostics.PerformanceCounter", PERFCTR_1) ICALL(PERFCTR_1, "FreeData", mono_perfcounter_free_data) ICALL(PERFCTR_2, "GetImpl", mono_perfcounter_get_impl) @@ -572,7 +572,7 @@ ICALL(TYPEB_7, "setup_internal_class", mono_reflection_setup_internal_class) ICALL_TYPE(FIELDI, "System.Reflection.FieldInfo", FILEDI_1) ICALL(FILEDI_1, "GetTypeModifiers", ves_icall_System_Reflection_FieldInfo_GetTypeModifiers) -ICALL(FILEDI_2, "GetUnmanagedMarshal", ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal) +ICALL(FILEDI_2, "get_marshal_info", ves_icall_System_Reflection_FieldInfo_get_marshal_info) ICALL(FILEDI_3, "internal_from_handle_type", ves_icall_System_Reflection_FieldInfo_internal_from_handle_type) ICALL_TYPE(MEMBERI, "System.Reflection.MemberInfo", MEMBERI_1) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index e58903aa88a..0719d488384 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1641,8 +1641,8 @@ ves_icall_get_attributes (MonoReflectionType *type) return klass->flags; } -ICALL_EXPORT MonoReflectionMarshal* -ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field) +ICALL_EXPORT MonoReflectionMarshalAsAttribute* +ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field) { MonoClass *klass = field->field->parent; MonoMarshalType *info; @@ -1659,7 +1659,7 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField * if (!info->fields [i].mspec) return NULL; else - return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec); + return mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec); } } @@ -1749,11 +1749,11 @@ ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member) return mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL); } -ICALL_EXPORT MonoReflectionMarshal* +ICALL_EXPORT MonoReflectionMarshalAsAttribute* ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method) { MonoDomain *domain = mono_domain_get (); - MonoReflectionMarshal* res = NULL; + MonoReflectionMarshalAsAttribute* res = NULL; MonoMarshalSpec **mspecs; int i; @@ -1761,7 +1761,7 @@ ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method) mono_method_get_marshal_info (method, mspecs); if (mspecs [0]) - res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]); + res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0]); for (i = mono_method_signature (method)->param_count; i >= 0; i--) if (mspecs [i]) @@ -6254,6 +6254,10 @@ ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, Mo MONO_ARCH_SAVE_REGS; + /* This is called directly from the class libraries without going through the managed wrapper */ + MONO_CHECK_ARG_NULL (src); + MONO_CHECK_ARG_NULL (dest); + /* watch out for integer overflow */ if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count)) return FALSE; diff --git a/mono/metadata/image.c b/mono/metadata/image.c index 3cf7ee51666..763aa720af8 100644 --- a/mono/metadata/image.c +++ b/mono/metadata/image.c @@ -1729,7 +1729,9 @@ mono_image_close_finish (MonoImage *image) if (image->modules) g_free (image->modules); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes -= mono_mempool_get_allocated (image->mempool); +#endif if (!image->dynamic) { if (debug_assembly_unload) @@ -2225,7 +2227,9 @@ mono_image_alloc (MonoImage *image, guint size) { gpointer res; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += size; +#endif mono_image_lock (image); res = mono_mempool_alloc (image->mempool, size); mono_image_unlock (image); @@ -2238,7 +2242,9 @@ mono_image_alloc0 (MonoImage *image, guint size) { gpointer res; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += size; +#endif mono_image_lock (image); res = mono_mempool_alloc0 (image->mempool, size); mono_image_unlock (image); @@ -2251,7 +2257,9 @@ mono_image_strdup (MonoImage *image, const char *s) { char *res; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += strlen (s); +#endif mono_image_lock (image); res = mono_mempool_strdup (image->mempool, s); mono_image_unlock (image); diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index e890bab6019..259c5f2f548 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -835,9 +835,11 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to if (method->klass->generic_class) return mono_method_signature (method); +#ifndef DISABLE_REFLECTION_EMIT if (image->dynamic) { sig = mono_reflection_lookup_signature (image, method, token); } else { +#endif mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); sig_idx = cols [MONO_MEMBERREF_SIGNATURE]; @@ -866,7 +868,9 @@ mono_method_get_signature_full (MonoMethod *method, MonoImage *image, guint32 to mono_loader_set_error_bad_image (g_strdup_printf ("Incompatible method signature class token 0x%08x field name %s token 0x%08x on image %s", class, fname, token, image->name)); return NULL; } +#ifndef DISABLE_REFLECTION_EMIT } +#endif if (context) { diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index d6f921d6114..d62ea3699c1 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -1962,6 +1962,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje break; } case MONO_TYPE_OBJECT: { +#ifndef DISABLE_COM mono_init_com_types (); if (to_object) { static MonoMethod *variant_clear = NULL; @@ -1989,7 +1990,11 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje mono_mb_emit_byte(mb, CEE_LDIND_REF); mono_mb_emit_ldloc (mb, 1); mono_mb_emit_managed_call (mb, get_native_variant_for_object, NULL); - } + } +#else + char *msg = g_strdup_printf ("COM support was disabled at compilation time."); + mono_mb_emit_exception_marshal_directive (mb, msg); +#endif break; } @@ -2920,18 +2925,16 @@ mono_marshal_get_remoting_invoke (MonoMethod *method) return method; /* this seems to be the best plase to put this, as all remoting invokes seem to get filtered through here */ +#ifndef DISABLE_COM if (method->klass->is_com_object || method->klass == mono_defaults.com_object_class) { MonoVTable *vtable = mono_class_vtable (mono_domain_get (), method->klass); g_assert (vtable); /*FIXME do proper error handling*/ if (!vtable->remote) { -#ifndef DISABLE_COM return mono_cominterop_get_invoke (method); -#else - g_assert_not_reached (); -#endif } } +#endif sig = mono_signature_no_pinvoke (method); @@ -6965,6 +6968,9 @@ emit_marshal_object (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } + +#ifndef DISABLE_COM + static int emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, @@ -7080,6 +7086,8 @@ emit_marshal_variant (EmitMarshalContext *m, int argnum, MonoType *t, return conv_arg; } +#endif /* DISABLE_COM */ + static gboolean mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo) { @@ -8076,10 +8084,10 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t, return emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action); case MONO_TYPE_CLASS: case MONO_TYPE_OBJECT: +#ifndef DISABLE_COM if (spec && spec->native == MONO_NATIVE_STRUCT) return emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action); -#ifndef DISABLE_COM if (spec && (spec->native == MONO_NATIVE_IUNKNOWN || spec->native == MONO_NATIVE_IDISPATCH || spec->native == MONO_NATIVE_INTERFACE)) diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index ba794c6b3de..72991f977fa 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -138,7 +138,7 @@ const static unsigned char coded_index_desc[] = { 5, /*tables*/ MONO_TABLE_TYPEDEF, MONO_TABLE_TYPEREF, - MONO_TABLE_MODULE, + MONO_TABLE_MODULEREF, MONO_TABLE_METHOD, MONO_TABLE_TYPESPEC, diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index bd07b1ff97c..7f5a1757a1b 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -757,7 +757,6 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows); n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows); n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows); - n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows); /* 3 bits to encode */ field_size = rtsize (n, 16 - 3); diff --git a/mono/metadata/monitor.c b/mono/metadata/monitor.c index 5b2d7ecfb5b..2d1f0545623 100644 --- a/mono/metadata/monitor.c +++ b/mono/metadata/monitor.c @@ -242,7 +242,9 @@ mon_finalize (MonoThreadsSync *mon) mon->data = monitor_freelist; monitor_freelist = mon; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_sync_blocks--; +#endif } /* LOCKING: this is called with monitor_mutex held */ @@ -310,7 +312,9 @@ mon_new (gsize id) new->owner = id; new->nest = 1; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_sync_blocks++; +#endif return new; } @@ -536,7 +540,9 @@ retry: } /* The object must be locked by someone else... */ +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->thread_contentions++; +#endif /* If ms is 0 we don't block, but just fail straight away */ if (ms == 0) { @@ -612,8 +618,10 @@ retry_contended: InterlockedIncrement (&mon->entry_count); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->thread_queue_len++; mono_perfcounters->thread_queue_max++; +#endif thread = mono_thread_internal_current (); mono_thread_set_state (thread, ThreadState_WaitSleepJoin); @@ -627,7 +635,9 @@ retry_contended: mono_thread_clr_state (thread, ThreadState_WaitSleepJoin); InterlockedDecrement (&mon->entry_count); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->thread_queue_len--; +#endif if (ms != INFINITE) { now = mono_msec_ticks (); diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c index 0391408b6d3..9743232da1b 100644 --- a/mono/metadata/mono-debug.c +++ b/mono/metadata/mono-debug.c @@ -198,7 +198,10 @@ lookup_data_table (MonoDomain *domain) MonoDebugDataTable *table; table = g_hash_table_lookup (data_table_hash, domain); - g_assert (table); + if (!table) { + g_error ("lookup_data_table () failed for %p\n", domain); + g_assert (table); + } return table; } diff --git a/mono/metadata/mono-perfcounters.c b/mono/metadata/mono-perfcounters.c index dfe7b4b4d3d..700cd9e498a 100644 --- a/mono/metadata/mono-perfcounters.c +++ b/mono/metadata/mono-perfcounters.c @@ -52,6 +52,7 @@ struct _MonoCounterSample { int counterType; }; +#ifndef DISABLE_PERFCOUNTERS /* map of PerformanceCounterType.cs */ enum { NumberOfItemsHEX32=0x00000000, @@ -1689,4 +1690,77 @@ mono_perfcounter_instance_names (MonoString *category, MonoString *machine) return mono_array_new (mono_domain_get (), mono_get_string_class (), 0); } } +#else +void* +mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString* instance, MonoString* machine, int *type, MonoBoolean *custom) +{ + g_assert_not_reached (); +} + +MonoBoolean +mono_perfcounter_get_sample (void *impl, MonoBoolean only_value, MonoCounterSample *sample) +{ + g_assert_not_reached (); +} + +gint64 +mono_perfcounter_update_value (void *impl, MonoBoolean do_incr, gint64 value) +{ + g_assert_not_reached (); +} + +void +mono_perfcounter_free_data (void *impl) +{ + g_assert_not_reached (); +} + +/* Category icalls */ +MonoBoolean +mono_perfcounter_category_del (MonoString *name) +{ + g_assert_not_reached (); +} + +MonoString* +mono_perfcounter_category_help (MonoString *category, MonoString *machine) +{ + g_assert_not_reached (); +} +MonoBoolean +mono_perfcounter_category_exists (MonoString *counter, MonoString *category, MonoString *machine) +{ + g_assert_not_reached (); +} + +MonoBoolean +mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoArray *items) +{ + g_assert_not_reached (); +} + +int +mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, MonoString *machine) +{ + g_assert_not_reached (); +} + +MonoArray* +mono_perfcounter_category_names (MonoString *machine) +{ + g_assert_not_reached (); +} + +MonoArray* +mono_perfcounter_counter_names (MonoString *category, MonoString *machine) +{ + g_assert_not_reached (); +} + +MonoArray* +mono_perfcounter_instance_names (MonoString *category, MonoString *machine) +{ + g_assert_not_reached (); +} +#endif diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index 0d2f4598995..e59a4d4eb9c 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -83,7 +83,7 @@ #endif #define MONO_CHECK_ARG(arg, expr) G_STMT_START{ \ - if (!(expr)) \ + if (G_UNLIKELY (!(expr))) \ { \ MonoException *ex; \ char *msg = g_strdup_printf ("assertion `%s' failed", \ @@ -95,7 +95,7 @@ }; }G_STMT_END #define MONO_CHECK_ARG_NULL(arg) G_STMT_START{ \ - if (arg == NULL) \ + if (G_UNLIKELY (arg == NULL)) \ { \ MonoException *ex; \ if (arg) {} /* check if the name exists */ \ @@ -1226,6 +1226,21 @@ typedef struct { MonoArray *data; } MonoReflectionCustomAttr; +typedef struct { + MonoObject object; + MonoString *marshal_cookie; + MonoString *marshal_type; + MonoReflectionType *marshal_type_ref; + MonoReflectionType *marshal_safe_array_user_defined_subtype; + guint32 utype; + guint32 array_subtype; + gint32 safe_array_subtype; + gint32 size_const; + gint32 IidParameterIndex; + gint16 size_param_index; +} MonoReflectionMarshalAsAttribute; + + typedef struct { MonoObject object; gint32 call_conv; @@ -1398,7 +1413,7 @@ MonoArray *mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelp MonoArray *mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig) MONO_INTERNAL; -MonoReflectionMarshal* mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass, MonoMarshalSpec *spec) MONO_INTERNAL; +MonoReflectionMarshalAsAttribute* mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass, MonoMarshalSpec *spec) MONO_INTERNAL; gpointer mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context) MONO_INTERNAL; diff --git a/mono/metadata/object.c b/mono/metadata/object.c index a1e1f884125..48ced0faa55 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -2538,7 +2538,9 @@ mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_ rc->default_vtable = NULL; rc->xdomain_vtable = NULL; rc->proxy_class_name = name; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->loader_bytes += mono_string_length (class_name) + 1; +#endif g_hash_table_insert (domain->proxy_vtable_hash, key, rc); @@ -2617,9 +2619,11 @@ mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, Mon MonoClass *klass; type = ((MonoReflectionType *)rp->class_to_proxy)->type; klass = mono_class_from_mono_type (type); +#ifndef DISABLE_COM if ((klass->is_com_object || (mono_defaults.com_object_class && klass == mono_defaults.com_object_class)) && !mono_class_vtable (mono_domain_get (), klass)->remote) remote_class->default_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_COMINTEROP); else +#endif remote_class->default_vtable = mono_class_proxy_vtable (domain, remote_class, MONO_REMOTING_TARGET_UNKNOWN); } diff --git a/mono/metadata/pedump.c b/mono/metadata/pedump.c index d6c159dcf30..ee7af61a57a 100644 --- a/mono/metadata/pedump.c +++ b/mono/metadata/pedump.c @@ -649,7 +649,9 @@ main (int argc, char *argv []) if (!file) usage (); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters_init (); +#endif mono_metadata_init (); mono_images_init (); mono_assemblies_init (); diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index 79e285b43cf..0c3d2364822 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -6862,7 +6862,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla } if (mspecs [i + 1]) - MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1])); + MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1])); mono_array_setref (res, i, param); } @@ -10019,45 +10019,46 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly, } #endif /* !DISABLE_REFLECTION_EMIT */ -MonoReflectionMarshal* -mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass, +MonoReflectionMarshalAsAttribute* +mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass, MonoMarshalSpec *spec) { - static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass; - MonoReflectionMarshal *minfo; + static MonoClass *System_Reflection_Emit_MarshalAsAttribute; + MonoReflectionMarshalAsAttribute *minfo; MonoType *mtype; - if (!System_Reflection_Emit_UnmanagedMarshalClass) { - System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name ( - mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal"); - g_assert (System_Reflection_Emit_UnmanagedMarshalClass); + if (!System_Reflection_Emit_MarshalAsAttribute) { + System_Reflection_Emit_MarshalAsAttribute = mono_class_from_name ( + mono_defaults.corlib, "System.Runtime.InteropServices", "MarshalAsAttribute"); + g_assert (System_Reflection_Emit_MarshalAsAttribute); } - minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass); - minfo->type = spec->native; + minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new (domain, System_Reflection_Emit_MarshalAsAttribute); + minfo->utype = spec->native; - switch (minfo->type) { + switch (minfo->utype) { case MONO_NATIVE_LPARRAY: - minfo->eltype = spec->data.array_data.elem_type; - minfo->count = spec->data.array_data.num_elem; - minfo->param_num = spec->data.array_data.param_num; + minfo->array_subtype = spec->data.array_data.elem_type; + minfo->size_const = spec->data.array_data.num_elem; + if (spec->data.array_data.param_num != -1) + minfo->size_param_index = spec->data.array_data.param_num; break; case MONO_NATIVE_BYVALTSTR: case MONO_NATIVE_BYVALARRAY: - minfo->count = spec->data.array_data.num_elem; + minfo->size_const = spec->data.array_data.num_elem; break; case MONO_NATIVE_CUSTOM: if (spec->data.custom_data.custom_name) { mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image); if (mtype) - MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype)); + MONO_OBJECT_SETREF (minfo, marshal_type_ref, mono_type_get_object (domain, mtype)); - MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name)); + MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name)); } if (spec->data.custom_data.cookie) - MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie)); + MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie)); break; default: diff --git a/mono/metadata/sgen-alloc.c b/mono/metadata/sgen-alloc.c index 1f21fdd2feb..c923c6322bc 100644 --- a/mono/metadata/sgen-alloc.c +++ b/mono/metadata/sgen-alloc.c @@ -8,25 +8,20 @@ * Copyright 2005-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright 2011 Xamarin, Inc. + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -223,7 +218,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) * visible before the vtable store. */ - DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size)); + SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p , vtable, size); if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) MONO_GC_NURSERY_OBJ_ALLOC ((mword)p, size, vtable->klass->name_space, vtable->klass->name); @@ -284,7 +279,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) } else { size_t alloc_size = 0; if (TLAB_START) - DEBUG (3, fprintf (gc_debug_file, "Retire TLAB: %p-%p [%ld]\n", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size))); + SGEN_LOG (3, "Retire TLAB: %p-%p [%ld]", TLAB_START, TLAB_REAL_END, (long)(TLAB_REAL_END - TLAB_NEXT - size)); sgen_nursery_retire_region (p, available_in_tlab); do { @@ -325,12 +320,12 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) sgen_set_nursery_scan_start ((char*)p); /* we just bump tlab_temp_end as well */ TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE); - DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", TLAB_NEXT, TLAB_TEMP_END)); + SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END); } } if (G_LIKELY (p)) { - DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size)); + SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p, vtable, size); if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()|| MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) { if (size > SGEN_MAX_SMALL_OBJ_SIZE) @@ -387,7 +382,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size) sgen_set_nursery_scan_start (new_next); /* we just bump tlab_temp_end as well */ TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE); - DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", TLAB_NEXT, TLAB_TEMP_END)); + SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END); } } else if (available_in_tlab > SGEN_MAX_NURSERY_WASTE) { /* Allocate directly from the nursery */ @@ -422,7 +417,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size) HEAVY_STAT (++stat_objects_alloced); HEAVY_STAT (stat_bytes_alloced += size); - DEBUG (6, fprintf (gc_debug_file, "Allocated object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size)); + SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p, vtable, size); if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) MONO_GC_NURSERY_OBJ_ALLOC ((mword)p, size, vtable->klass->name_space, vtable->klass->name); @@ -574,11 +569,11 @@ mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size) /* large objects are always pinned anyway */ p = sgen_los_alloc_large_inner (vtable, size); } else { - DEBUG (9, g_assert (vtable->klass->inited)); + SGEN_ASSERT (9, vtable->klass->inited, "class %s:%s is not initialized", vtable->klass->name_space, vtable->klass->name); p = major_collector.alloc_small_pinned_obj (size, SGEN_VTABLE_HAS_REFERENCES (vtable)); } if (G_LIKELY (p)) { - DEBUG (6, fprintf (gc_debug_file, "Allocated pinned object %p, vtable: %p (%s), size: %zd\n", p, vtable, vtable->klass->name, size)); + SGEN_LOG (6, "Allocated pinned object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); if (size > SGEN_MAX_SMALL_OBJ_SIZE) MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword)p, size, vtable->klass->name_space, vtable->klass->name); else diff --git a/mono/metadata/sgen-archdep.h b/mono/metadata/sgen-archdep.h index 5da555bf5b4..c41e73808e6 100644 --- a/mono/metadata/sgen-archdep.h +++ b/mono/metadata/sgen-archdep.h @@ -1,34 +1,39 @@ /* - * SGen is licensed under the terms of the MIT X11 license + * sgen-archdep.h: Architecture dependent parts of SGen. * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MONO_SGENARCHDEP_H__ #define __MONO_SGENARCHDEP_H__ #include -#if defined(__i386__) || defined(TARGET_X86) +#if defined(MONO_CROSS_COMPILE) + +#define REDZONE_SIZE 0 + +#define ARCH_NUM_REGS 0 +#define ARCH_STORE_REGS(ptr) +#define ARCH_SIGCTX_SP(ctx) NULL +#define ARCH_SIGCTX_IP(ctx) NULL +#define ARCH_COPY_SIGCTX_REGS(a,ctx) + +#elif defined(TARGET_X86) #include @@ -71,7 +76,7 @@ #define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_ESP ((ctx))) #define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_EIP ((ctx))) -#elif defined(__x86_64__) || defined(TARGET_AMD64) +#elif defined(TARGET_AMD64) #include @@ -84,7 +89,7 @@ #define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_RSP (ctx)) #define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_RIP (ctx)) -#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +#elif defined(TARGET_PPC) #define REDZONE_SIZE 224 @@ -112,9 +117,10 @@ ((a)[__i]) = UCONTEXT_REG_Rn((ctx), __i); \ } while (0) -#elif defined(__arm__) +#elif defined(TARGET_ARM) #define REDZONE_SIZE 0 +#define USE_MONO_CTX /* We dont store ip, sp */ #define ARCH_NUM_REGS 14 diff --git a/mono/metadata/sgen-cardtable.c b/mono/metadata/sgen-cardtable.c index 4fad8b6678a..3976a0d833e 100644 --- a/mono/metadata/sgen-cardtable.c +++ b/mono/metadata/sgen-cardtable.c @@ -599,7 +599,7 @@ LOOP_HEAD: #ifdef CARDTABLE_STATS typedef struct { - int total, marked, remarked; + int total, marked, remarked, gc_marked; } card_stats; static card_stats major_stats, los_stats; @@ -610,9 +610,12 @@ count_marked_cards (mword start, mword size) { mword end = start + size; while (start <= end) { + guint8 card = *sgen_card_table_get_card_address (start); ++cur_stats->total; - if (sgen_card_table_address_is_marked (start)) + if (card) ++cur_stats->marked; + if (card == 2) + ++cur_stats->gc_marked; start += CARD_SIZE_IN_BYTES; } } @@ -622,8 +625,10 @@ count_remarked_cards (mword start, mword size) { mword end = start + size; while (start <= end) { - if (sgen_card_table_address_is_marked (start)) + if (sgen_card_table_address_is_marked (start)) { ++cur_stats->remarked; + *sgen_card_table_get_card_address (start) = 2; + } start += CARD_SIZE_IN_BYTES; } } @@ -643,12 +648,12 @@ sgen_card_tables_collect_stats (gboolean begin) sgen_los_iterate_live_block_ranges (count_marked_cards); } else { cur_stats = &major_stats; - sgen_major_collector_iterate_live_block_ranges (count_marked_cards); + sgen_major_collector_iterate_live_block_ranges (count_remarked_cards); cur_stats = &los_stats; sgen_los_iterate_live_block_ranges (count_remarked_cards); - printf ("cards major (t %d m %d r %d) los (t %d m %d r %d) major_scan %.2fms los_scan %.2fms\n", - major_stats.total, major_stats.marked, major_stats.remarked, - los_stats.total, los_stats.marked, los_stats.remarked, + printf ("cards major (t %d m %d g %d r %d) los (t %d m %d g %d r %d) major_scan %.2fms los_scan %.2fms\n", + major_stats.total, major_stats.marked, major_stats.gc_marked, major_stats.remarked, + los_stats.total, los_stats.marked, los_stats.gc_marked, los_stats.remarked, last_major_scan_time / 1000.0, last_los_scan_time / 1000.0); } #endif diff --git a/mono/metadata/sgen-conf.h b/mono/metadata/sgen-conf.h index 19f28cde038..2eb703e9abc 100644 --- a/mono/metadata/sgen-conf.h +++ b/mono/metadata/sgen-conf.h @@ -1,26 +1,23 @@ /* + * sgen-conf.h: Tunable parameters and debugging switches. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MONO_SGENCONF_H__ #define __MONO_SGENCONF_H__ @@ -82,11 +79,17 @@ typedef guint64 mword; /* * Maximum level of debug to enable on this build. - * Making this a static variable enables us to put logging in a lot of places. - * FIXME decouple logging from assertions + * Making this a constant enables us to put logging in a lot of places and + * not pay its cost on release builds. */ #define SGEN_MAX_DEBUG_LEVEL 2 +/* + * Maximum level of asserts to enable on this build. + * FIXME replace all magic numbers with defines. + */ +#define SGEN_MAX_ASSERT_LEVEL 2 + #define GC_BITS_PER_WORD (sizeof (mword) * 8) diff --git a/mono/metadata/sgen-copy-object.h b/mono/metadata/sgen-copy-object.h index c1404df1943..76a00e281ac 100644 --- a/mono/metadata/sgen-copy-object.h +++ b/mono/metadata/sgen-copy-object.h @@ -1,25 +1,22 @@ /* + * sgen-copy-object.h: This is where objects are copied. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ extern long long stat_copy_object_called_nursery; extern long long stat_objects_copied_nursery; @@ -41,8 +38,8 @@ par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword o static const void *copy_labels [] = { &&LAB_0, &&LAB_1, &&LAB_2, &&LAB_3, &&LAB_4, &&LAB_5, &&LAB_6, &&LAB_7, &&LAB_8 }; #endif - DEBUG (9, g_assert (vt->klass->inited)); - DEBUG (9, fprintf (gc_debug_file, " (to %p, %s size: %lu)\n", destination, ((MonoObject*)obj)->vtable->klass->name, (unsigned long)objsize)); + SGEN_ASSERT (9, vt->klass->inited, "vtable %p for class %s:%s was not initialized", vt, vt->klass->name_space, vt->klass->name); + SGEN_LOG (9, " (to %p, %s size: %lu)", destination, ((MonoObject*)obj)->vtable->klass->name, (unsigned long)objsize); binary_protocol_copy (obj, destination, vt, objsize); if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) { @@ -81,21 +78,25 @@ par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword o mono_gc_memmove (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword)); #endif /* adjust array->bounds */ - DEBUG (9, g_assert (vt->gc_descr)); + SGEN_ASSERT (9, vt->gc_descr, "vtable %p for class %s:%s has no gc descriptor", vt, vt->klass->name_space, vt->klass->name); + if (G_UNLIKELY (vt->rank && ((MonoArray*)obj)->bounds)) { MonoArray *array = (MonoArray*)destination; array->bounds = (MonoArrayBounds*)((char*)destination + ((char*)((MonoArray*)obj)->bounds - (char*)obj)); - DEBUG (9, fprintf (gc_debug_file, "Array instance %p: size: %lu, rank: %d, length: %lu\n", array, (unsigned long)objsize, vt->rank, (unsigned long)mono_array_length (array))); + SGEN_LOG (9, "Array instance %p: size: %lu, rank: %d, length: %lu", array, (unsigned long)objsize, vt->rank, (unsigned long)mono_array_length (array)); } if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_GC_MOVES)) sgen_register_moved_object (obj, destination); obj = destination; if (queue) { - DEBUG (9, fprintf (gc_debug_file, "Enqueuing gray object %p (%s)\n", obj, sgen_safe_name (obj))); + SGEN_LOG (9, "Enqueuing gray object %p (%s)", obj, sgen_safe_name (obj)); GRAY_OBJECT_ENQUEUE (queue, obj); } } +/* + * This can return OBJ itself on OOM. + */ #ifdef _MSC_VER static __declspec(noinline) void* #else @@ -106,7 +107,7 @@ copy_object_no_checks (void *obj, SgenGrayQueue *queue) MonoVTable *vt = ((MonoObject*)obj)->vtable; gboolean has_references = SGEN_VTABLE_HAS_REFERENCES (vt); mword objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); - char *destination = collector_serial_alloc_for_promotion (obj, objsize, has_references); + char *destination = COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION (obj, objsize, has_references); if (G_UNLIKELY (!destination)) { collector_pin_object (obj, queue); @@ -122,176 +123,3 @@ copy_object_no_checks (void *obj, SgenGrayQueue *queue) return destination; } - -#ifdef GENERATE_COPY_FUNCTIONS - -extern long long stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */ - -#if defined(SGEN_SIMPLE_NURSERY) -#define serial_copy_object simple_nursery_serial_copy_object -#define parallel_copy_object simple_nursery_parallel_copy_object - -#elif defined (SGEN_SPLIT_NURSERY) - -#define serial_copy_object split_nursery_serial_copy_object -#define parallel_copy_object split_nursery_parallel_copy_object - -#else -#error "Please define GC_CONF_NAME" -#endif - -/* - * This is how the copying happens from the nursery to the old generation. - * We assume that at this time all the pinned objects have been identified and - * marked as such. - * We run scan_object() for each pinned object so that each referenced - * objects if possible are copied. The new gray objects created can have - * scan_object() run on them right away, too. - * Then we run copy_object() for the precisely tracked roots. At this point - * all the roots are either gray or black. We run scan_object() on the gray - * objects until no more gray objects are created. - * At the end of the process we walk again the pinned list and we unmark - * the pinned flag. As we go we also create the list of free space for use - * in the next allocation runs. - * - * We need to remember objects from the old generation that point to the new one - * (or just addresses?). - * - * copy_object could be made into a macro once debugged (use inline for now). - */ - -#ifdef _MSC_VER -static __forceinline void -#else -static inline void __attribute__((always_inline)) -#endif -serial_copy_object (void **obj_slot, SgenGrayQueue *queue) -{ - char *forwarded; - char *obj = *obj_slot; - - DEBUG (9, g_assert (current_collection_generation == GENERATION_NURSERY)); - - HEAVY_STAT (++stat_copy_object_called_nursery); - - if (!sgen_ptr_in_nursery (obj)) { - HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); - return; - } - - DEBUG (9, fprintf (gc_debug_file, "Precise copy of %p from %p", obj, obj_slot)); - - /* - * Before we can copy the object we must make sure that we are - * allowed to, i.e. that the object not pinned, not already - * forwarded or belongs to the nursery To Space. - */ - - if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { - DEBUG (9, g_assert ((*(MonoVTable**)SGEN_LOAD_VTABLE(obj))->gc_descr)); - DEBUG (9, fprintf (gc_debug_file, " (already forwarded to %p)\n", forwarded)); - HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); - *obj_slot = forwarded; - return; - } - if (SGEN_OBJECT_IS_PINNED (obj)) { - DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr)); - DEBUG (9, fprintf (gc_debug_file, " (pinned, no change)\n")); - HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); - return; - } - - if (sgen_nursery_is_to_space (obj)) { - DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr)); - DEBUG (9, fprintf (gc_debug_file, " (tospace, no change)\n")); - HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); - return; - } - - HEAVY_STAT (++stat_objects_copied_nursery); - - *obj_slot = copy_object_no_checks (obj, queue); -} - -static void -parallel_copy_object (void **obj_slot, SgenGrayQueue *queue) -{ - char *obj = *obj_slot; - mword vtable_word, objsize; - MonoVTable *vt; - void *destination; - gboolean has_references; - - DEBUG (9, g_assert (current_collection_generation == GENERATION_NURSERY)); - - HEAVY_STAT (++stat_copy_object_called_nursery); - - if (!sgen_ptr_in_nursery (obj)) { - HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); - return; - } - - vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - /* - * Before we can copy the object we must make sure that we are - * allowed to, i.e. that the object not pinned, not already - * forwarded and not in the nursery To Space. - */ - - if (vtable_word & SGEN_FORWARDED_BIT) { - HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); - *obj_slot = vt; - return; - } - if (vtable_word & SGEN_PINNED_BIT) { - HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); - return; - } - - if (sgen_nursery_is_to_space (obj)) { - HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); - return; - } - - HEAVY_STAT (++stat_objects_copied_nursery); - - objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); - has_references = SGEN_VTABLE_HAS_REFERENCES (vt); - - destination = collector_parallel_alloc_for_promotion (obj, objsize, has_references); - - if (G_UNLIKELY (!destination)) { - sgen_parallel_pin_or_update (obj_slot, obj, vt, queue); - return; - } - - *(MonoVTable**)destination = vt; - - if (SGEN_CAS_PTR ((void*)obj, (void*)((mword)destination | SGEN_FORWARDED_BIT), vt) == vt) { - par_copy_object_no_checks (destination, vt, obj, objsize, has_references ? queue : NULL); - obj = destination; - *obj_slot = obj; - } else { - /* FIXME: unify with code in major_copy_or_mark_object() */ - - /* FIXME: Give destination back to the allocator. */ - /*The major collector only needs the first word zeroed and nursery requires all bits to be. */ - if (!sgen_ptr_in_nursery (destination)) - *(void**)destination = NULL; - else - memset (destination, 0, objsize); - - vtable_word = *(mword*)obj; - g_assert (vtable_word & SGEN_FORWARDED_BIT); - - obj = (void*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - *obj_slot = obj; - - HEAVY_STAT (++stat_slots_allocated_in_vain); - } -} - -#endif diff --git a/mono/metadata/sgen-debug.c b/mono/metadata/sgen-debug.c index bbc3478a95e..274e7e76b76 100644 --- a/mono/metadata/sgen-debug.c +++ b/mono/metadata/sgen-debug.c @@ -8,25 +8,20 @@ * Copyright 2005-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright 2011 Xamarin, Inc. + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -130,7 +125,7 @@ static gboolean missing_remsets; #define HANDLE_PTR(ptr,obj) do { \ if (*(ptr) && sgen_ptr_in_nursery ((char*)*(ptr))) { \ if (!sgen_get_remset ()->find_address ((char*)(ptr))) { \ - fprintf (gc_debug_file, "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.\n", *(ptr), (char*)(ptr) - (char*)(obj), (obj), ((MonoObject*)(obj))->vtable->klass->name_space, ((MonoObject*)(obj))->vtable->klass->name); \ + SGEN_LOG (1, "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), ((MonoObject*)(obj))->vtable->klass->name_space, ((MonoObject*)(obj))->vtable->klass->name); \ binary_protocol_missing_remset ((obj), (gpointer)LOAD_VTABLE ((obj)), (char*)(ptr) - (char*)(obj), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \ if (!object_is_pinned (*(ptr))) \ missing_remsets = TRUE; \ @@ -146,7 +141,7 @@ static void check_consistency_callback (char *start, size_t size, void *dummy) { GCVTable *vt = (GCVTable*)LOAD_VTABLE (start); - DEBUG (8, fprintf (gc_debug_file, "Scanning object %p, vtable: %p (%s)\n", start, vt, vt->klass->name)); + SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", start, vt, vt->klass->name); #define SCAN_OBJECT_ACTION #include "sgen-scan-object.h" @@ -164,14 +159,14 @@ sgen_check_consistency (void) missing_remsets = FALSE; - DEBUG (1, fprintf (gc_debug_file, "Begin heap consistency check...\n")); + SGEN_LOG (1, "Begin heap consistency check..."); // Check that oldspace->newspace pointers are registered with the collector major_collector.iterate_objects (TRUE, TRUE, (IterateObjectCallbackFunc)check_consistency_callback, NULL); sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_consistency_callback, NULL); - DEBUG (1, fprintf (gc_debug_file, "Heap consistency check done.\n")); + SGEN_LOG (1, "Heap consistency check done."); if (!binary_protocol_is_enabled ()) g_assert (!missing_remsets); @@ -255,24 +250,23 @@ describe_nursery_ptr (char *ptr) { int i; - fprintf (gc_debug_file, "nursery-ptr "); for (i = 0; i < valid_nursery_object_count; ++i) { if (valid_nursery_objects [i] >= ptr) break; } if (i >= valid_nursery_object_count || valid_nursery_objects [i] + safe_object_get_size ((MonoObject *)valid_nursery_objects [i]) < ptr) { - fprintf (gc_debug_file, "(unalloc'd-memory)"); + SGEN_LOG (1, "nursery-ptr (unalloc'd-memory)"); } else { char *obj = valid_nursery_objects [i]; MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj); int size = safe_object_get_size ((MonoObject *)obj); if (obj == ptr) - fprintf (gc_debug_file, "(object %s.%s size %d)", + SGEN_LOG (1, "nursery-ptr (object %s.%s size %d)", vtable->klass->name_space, vtable->klass->name, size); else - fprintf (gc_debug_file, "(interior-ptr offset %td of %p (%s.%s) size %d)", + SGEN_LOG (1, "nursery-ptr (interior-ptr offset %td of %p (%s.%s) size %d)", ptr - obj, obj, vtable->klass->name_space, vtable->klass->name, size); } @@ -301,7 +295,7 @@ describe_pointer (char *ptr) } else if (major_collector.describe_pointer (ptr)) { //Nothing really } else if (!mono_sgen_los_describe_pointer (ptr)) { - fprintf (gc_debug_file, "non-heap-ptr"); + SGEN_LOG (1, "\tnon-heap-ptr"); } } @@ -311,11 +305,10 @@ bad_pointer_spew (char *obj, char **slot) char *ptr = *slot; MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj); - fprintf (gc_debug_file, "Invalid object pointer %p [", ptr); - describe_pointer (ptr); - fprintf (gc_debug_file, "] at offset %td in object %p (%s.%s).\n", + SGEN_LOG (1, "Invalid object pointer %p at offset %td in object %p (%s.%s):", ptr, (char*)slot - obj, obj, vtable->klass->name_space, vtable->klass->name); + describe_pointer (ptr); broken_heap = TRUE; } @@ -325,7 +318,7 @@ missing_remset_spew (char *obj, char **slot) char *ptr = *slot; MonoVTable *vtable = (MonoVTable*)LOAD_VTABLE (obj); - fprintf (gc_debug_file, "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.\n", + SGEN_LOG (1, "Oldspace->newspace reference %p at offset %td in object %p (%s.%s) not found in remsets.", ptr, (char*)slot - obj, obj, vtable->klass->name_space, vtable->klass->name); @@ -413,7 +406,7 @@ find_pinning_ref_from_thread (char *obj, size_t size) continue; while (start < (char**)info->stack_end) { if (*start >= obj && *start < endobj) { - DEBUG (0, fprintf (gc_debug_file, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p\n", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->stack_start, info->stack_end)); + SGEN_LOG (1, "Object %p referenced in thread %p (id %p) at %p, stack: %p-%p", obj, info, (gpointer)mono_thread_info_get_tid (info), start, info->stack_start, info->stack_end); } start++; } @@ -426,7 +419,7 @@ find_pinning_ref_from_thread (char *obj, size_t size) #endif if (w >= (mword)obj && w < (mword)obj + size) - DEBUG (0, fprintf (gc_debug_file, "Object %p referenced in saved reg %d of thread %p (id %p)\n", obj, j, info, (gpointer)mono_thread_info_get_tid (info))); + SGEN_LOG (1, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, j, info, (gpointer)mono_thread_info_get_tid (info)); } END_FOREACH_THREAD } } @@ -446,7 +439,7 @@ find_pinning_reference (char *obj, size_t size) if (!root->root_desc) { while (start < (char**)root->end_root) { if (*start >= obj && *start < endobj) { - DEBUG (0, fprintf (gc_debug_file, "Object %p referenced in pinned roots %p-%p\n", obj, start, root->end_root)); + SGEN_LOG (1, "Object %p referenced in pinned roots %p-%p\n", obj, start, root->end_root); } start++; } diff --git a/mono/metadata/sgen-descriptor.c b/mono/metadata/sgen-descriptor.c index 13d0e117233..286c186cf3c 100644 --- a/mono/metadata/sgen-descriptor.c +++ b/mono/metadata/sgen-descriptor.c @@ -1,26 +1,23 @@ /* + * sgen-descriptor.c: GC descriptors describe object layout. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #ifdef HAVE_SGEN_GC @@ -97,12 +94,12 @@ alloc_complex_descriptor (gsize *bitmap, int numbits) complex_descriptors = g_realloc (complex_descriptors, new_size * sizeof (gsize)); complex_descriptors_size = new_size; } - DEBUG (6, fprintf (gc_debug_file, "Complex descriptor %d, size: %d (total desc memory: %d)\n", res, nwords, complex_descriptors_size)); + SGEN_LOG (6, "Complex descriptor %d, size: %d (total desc memory: %d)", res, nwords, complex_descriptors_size); complex_descriptors_next += nwords; complex_descriptors [res] = nwords; for (i = 0; i < nwords - 1; ++i) { complex_descriptors [res + 1 + i] = bitmap [i]; - DEBUG (6, fprintf (gc_debug_file, "\tvalue: %p\n", (void*)complex_descriptors [res + 1 + i])); + SGEN_LOG (6, "\tvalue: %p", (void*)complex_descriptors [res + 1 + i]); } sgen_gc_unlock (); return res; @@ -143,7 +140,7 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size) } if (first_set < 0) { - DEBUG (6, fprintf (gc_debug_file, "Ptrfree descriptor %p, size: %zd\n", (void*)desc, stored_size)); + SGEN_LOG (6, "Ptrfree descriptor %p, size: %zd", (void*)desc, stored_size); if (stored_size <= MAX_RUNLEN_OBJECT_SIZE) return (void*)(DESC_TYPE_RUN_LENGTH | stored_size); return (void*)DESC_TYPE_COMPLEX_PTRFREE; @@ -158,7 +155,7 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size) */ if (first_set < 256 && num_set < 256 && (first_set + num_set == last_set + 1)) { desc = DESC_TYPE_RUN_LENGTH | stored_size | (first_set << 16) | (num_set << 24); - DEBUG (6, fprintf (gc_debug_file, "Runlen descriptor %p, size: %zd, first set: %d, num set: %d\n", (void*)desc, stored_size, first_set, num_set)); + SGEN_LOG (6, "Runlen descriptor %p, size: %zd, first set: %d, num set: %d", (void*)desc, stored_size, first_set, num_set); return (void*) desc; } } @@ -166,14 +163,14 @@ mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size) /* we know the 2-word header is ptr-free */ if (last_set < SMALL_BITMAP_SIZE + OBJECT_HEADER_WORDS) { desc = DESC_TYPE_SMALL_BITMAP | stored_size | ((*bitmap >> OBJECT_HEADER_WORDS) << SMALL_BITMAP_SHIFT); - DEBUG (6, fprintf (gc_debug_file, "Smallbitmap descriptor %p, size: %zd, last set: %d\n", (void*)desc, stored_size, last_set)); + SGEN_LOG (6, "Smallbitmap descriptor %p, size: %zd, last set: %d", (void*)desc, stored_size, last_set); return (void*) desc; } /* we know the 2-word header is ptr-free */ if (last_set < LARGE_BITMAP_SIZE + OBJECT_HEADER_WORDS) { desc = DESC_TYPE_LARGE_BITMAP | ((*bitmap >> OBJECT_HEADER_WORDS) << LOW_TYPE_BITS); - DEBUG (6, fprintf (gc_debug_file, "Largebitmap descriptor %p, size: %zd, last set: %d\n", (void*)desc, stored_size, last_set)); + SGEN_LOG (6, "Largebitmap descriptor %p, size: %zd, last set: %d", (void*)desc, stored_size, last_set); return (void*) desc; } /* it's a complex object ... */ diff --git a/mono/metadata/sgen-descriptor.h b/mono/metadata/sgen-descriptor.h index 4ce0de328e1..cd53a862c3d 100644 --- a/mono/metadata/sgen-descriptor.h +++ b/mono/metadata/sgen-descriptor.h @@ -1,26 +1,24 @@ /* + * sgen-descriptor.h: GC descriptors describe object layout. + * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MONO_SGEN_DESCRIPTOR_H__ #define __MONO_SGEN_DESCRIPTOR_H__ @@ -163,6 +161,8 @@ sgen_gc_descr_has_references (mword desc) void **_objptr = (void**)(obj); \ _objptr += ((desc) >> 16) & 0xff; \ _objptr_end = _objptr + (((desc) >> 24) & 0xff); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ while (_objptr < _objptr_end) { \ HANDLE_PTR (_objptr, (obj)); \ _objptr++; \ @@ -170,19 +170,42 @@ sgen_gc_descr_has_references (mword desc) } \ } while (0) +#ifdef __GNUC__ #define OBJ_BITMAP_FOREACH_PTR(desc,obj) do { \ /* there are pointers */ \ void **_objptr = (void**)(obj); \ gsize _bmap = (desc) >> 16; \ _objptr += OBJECT_HEADER_WORDS; \ + { \ + int _index = __builtin_ctz (_bmap); \ + _objptr += _index; \ + _bmap >>= (_index + 1); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ + } \ while (_bmap) { \ - if ((_bmap & 1)) { \ - HANDLE_PTR (_objptr, (obj)); \ - } \ - _bmap >>= 1; \ - ++_objptr; \ - } \ + int _index = __builtin_ctz (_bmap); \ + _objptr += _index; \ + _bmap >>= (_index + 1); \ + HANDLE_PTR (_objptr, (obj)); \ + _objptr ++; \ + } \ + } while (0) +#else +#define OBJ_BITMAP_FOREACH_PTR(desc,obj) do { \ + /* there are pointers */ \ + void **_objptr = (void**)(obj); \ + gsize _bmap = (desc) >> 16; \ + _objptr += OBJECT_HEADER_WORDS; \ + while (_bmap) { \ + if ((_bmap & 1)) { \ + HANDLE_PTR (_objptr, (obj)); \ + } \ + _bmap >>= 1; \ + ++_objptr; \ + } \ } while (0) +#endif /* a bitmap desc means that there are pointer references or we'd have * choosen run-length, instead: add an assert to check. diff --git a/mono/metadata/sgen-fin-weak-hash.c b/mono/metadata/sgen-fin-weak-hash.c index 9f3526815cf..20cff63039a 100644 --- a/mono/metadata/sgen-fin-weak-hash.c +++ b/mono/metadata/sgen-fin-weak-hash.c @@ -1,5 +1,5 @@ /* - * sgen-fin-weak-hash.c: + * sgen-fin-weak-hash.c: Finalizers and weak links. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -8,25 +8,20 @@ * Copyright 2005-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright 2011 Xamarin, Inc. + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -151,12 +146,12 @@ sgen_collect_bridge_objects (CopyOrMarkObjectFunc copy_func, char *start, char * /* insert it into the major hash */ sgen_hash_table_replace (&major_finalizable_hash, tagged_object_apply (copy, tag), NULL, NULL); - DEBUG (5, fprintf (gc_debug_file, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy, sgen_safe_name (copy), object)); + SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_safe_name (copy), object); continue; } else { /* update pointer */ - DEBUG (5, fprintf (gc_debug_file, "Updating object for finalization: %p (%s) (was at %p)\n", copy, sgen_safe_name (copy), object)); + SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_safe_name (copy), object); SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag)); } } SGEN_HASH_TABLE_FOREACH_END; @@ -186,7 +181,7 @@ sgen_finalize_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, num_ready_finalizers++; sgen_queue_finalization_entry (copy); /* Make it survive */ - DEBUG (5, fprintf (gc_debug_file, "Queueing object for finalization: %p (%s) (was at %p) (%d/%d)\n", copy, sgen_safe_name (copy), object, num_ready_finalizers, sgen_hash_table_num_entries (hash_table))); + SGEN_LOG (5, "Queueing object for finalization: %p (%s) (was at %p) (%d/%d)", copy, sgen_safe_name (copy), object, num_ready_finalizers, sgen_hash_table_num_entries (hash_table)); continue; } else { if (hash_table == &minor_finalizable_hash && !ptr_in_nursery (copy)) { @@ -196,12 +191,12 @@ sgen_finalize_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, /* insert it into the major hash */ sgen_hash_table_replace (&major_finalizable_hash, tagged_object_apply (copy, tag), NULL, NULL); - DEBUG (5, fprintf (gc_debug_file, "Promoting finalization of object %p (%s) (was at %p) to major table\n", copy, sgen_safe_name (copy), object)); + SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_safe_name (copy), object); continue; } else { /* update pointer */ - DEBUG (5, fprintf (gc_debug_file, "Updating object for finalization: %p (%s) (was at %p)\n", copy, sgen_safe_name (copy), object)); + SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_safe_name (copy), object); SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag)); } } @@ -222,10 +217,10 @@ register_for_finalization (MonoObject *obj, void *user_data, int generation) if (user_data) { if (sgen_hash_table_replace (hash_table, obj, NULL, NULL)) - DEBUG (5, fprintf (gc_debug_file, "Added finalizer for object: %p (%s) (%d) to %s table\n", obj, obj->vtable->klass->name, hash_table->num_entries, sgen_generation_name (generation))); + SGEN_LOG (5, "Added finalizer for object: %p (%s) (%d) to %s table", obj, obj->vtable->klass->name, hash_table->num_entries, sgen_generation_name (generation)); } else { if (sgen_hash_table_remove (hash_table, obj, NULL)) - DEBUG (5, fprintf (gc_debug_file, "Removed finalizer for object: %p (%s) (%d)\n", obj, obj->vtable->klass->name, hash_table->num_entries)); + SGEN_LOG (5, "Removed finalizer for object: %p (%s) (%d)", obj, obj->vtable->klass->name, hash_table->num_entries); } } @@ -356,7 +351,7 @@ finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size, /* remove and put in out_array */ SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); out_array [count ++] = object; - DEBUG (5, fprintf (gc_debug_file, "Collecting object for finalization: %p (%s) (%d/%d)\n", object, sgen_safe_name (object), num_ready_finalizers, sgen_hash_table_num_entries (hash_table))); + SGEN_LOG (5, "Collecting object for finalization: %p (%s) (%d/%d)", object, sgen_safe_name (object), num_ready_finalizers, sgen_hash_table_num_entries (hash_table)); if (count == out_size) return count; continue; @@ -416,15 +411,15 @@ add_or_remove_disappearing_link (MonoObject *obj, void **link, int generation) if (!obj) { if (sgen_hash_table_remove (hash_table, link, NULL)) { - DEBUG (5, fprintf (gc_debug_file, "Removed dislink %p (%d) from %s table\n", - link, hash_table->num_entries, sgen_generation_name (generation))); + SGEN_LOG (5, "Removed dislink %p (%d) from %s table", + link, hash_table->num_entries, sgen_generation_name (generation)); } return; } sgen_hash_table_replace (hash_table, link, NULL, NULL); - DEBUG (5, fprintf (gc_debug_file, "Added dislink for object: %p (%s) at %p to %s table\n", - obj, obj->vtable->klass->name, link, sgen_generation_name (generation))); + SGEN_LOG (5, "Added dislink for object: %p (%s) at %p to %s table", + obj, obj->vtable->klass->name, link, sgen_generation_name (generation)); } /* LOCKING: requires that the GC lock is held */ @@ -454,7 +449,7 @@ sgen_null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, if (object >= start && object < end && !major_collector.is_object_live (object)) { if (sgen_gc_is_object_ready_for_finalization (object)) { *link = NULL; - DEBUG (5, fprintf (gc_debug_file, "Dislink nullified at %p to GCed object %p\n", link, object)); + SGEN_LOG (5, "Dislink nullified at %p to GCed object %p", link, object); SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); continue; } else { @@ -476,12 +471,12 @@ sgen_null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, *link = HIDE_POINTER (copy, track); add_or_remove_disappearing_link ((MonoObject*)copy, link, GENERATION_OLD); - DEBUG (5, fprintf (gc_debug_file, "Upgraded dislink at %p to major because object %p moved to %p\n", link, object, copy)); + SGEN_LOG (5, "Upgraded dislink at %p to major because object %p moved to %p", link, object, copy); continue; } else { *link = HIDE_POINTER (copy, track); - DEBUG (5, fprintf (gc_debug_file, "Updated dislink at %p to %p\n", link, DISLINK_OBJECT (link))); + SGEN_LOG (5, "Updated dislink at %p to %p", link, DISLINK_OBJECT (link)); } } } @@ -508,7 +503,7 @@ sgen_null_links_for_domain (MonoDomain *domain, int generation) * This can happen if finalizers are not ran, i.e. Environment.Exit () * is called from finalizer like in finalizer-abort.cs. */ - DEBUG (5, fprintf (gc_debug_file, "Disappearing link %p not freed", link)); + SGEN_LOG (5, "Disappearing link %p not freed", link); } SGEN_HASH_TABLE_FOREACH_REMOVE (free); @@ -525,19 +520,13 @@ sgen_null_links_with_predicate (int generation, WeakLinkAlivePredicateFunc predi void **link; gpointer dummy; SgenHashTable *hash = get_dislink_hash_table (generation); - fprintf (stderr, "**** nulling links with predicate\n"); SGEN_HASH_TABLE_FOREACH (hash, link, dummy) { char *object = DISLINK_OBJECT (link); mono_bool is_alive = predicate ((MonoObject*)object, data); - if (is_alive) - fprintf (stderr, "ALIVE %p %s\n", object, sgen_safe_name (object)); - else - fprintf (stderr, "DEAD %p %s\n", object, sgen_safe_name (object)); - if (!is_alive) { *link = NULL; - DEBUG (5, fprintf (gc_debug_file, "Dislink nullified by predicate at %p to GCed object %p\n", link, object)); + SGEN_LOG (5, "Dislink nullified by predicate at %p to GCed object %p", link, object); SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); continue; } @@ -555,7 +544,7 @@ sgen_remove_finalizers_for_domain (MonoDomain *domain, int generation) object = tagged_object_get_object (object); if (mono_object_domain (object) == domain) { - DEBUG (5, fprintf (gc_debug_file, "Unregistering finalizer for object: %p (%s)\n", object, sgen_safe_name (object))); + SGEN_LOG (5, "Unregistering finalizer for object: %p (%s)", object, sgen_safe_name (object)); SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE); continue; diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index e9de61702b3..52bcbd5daa4 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -13,40 +13,23 @@ * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2004 by Hewlett-Packard Company. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 Xamarin, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Important: allocation provides always zeroed memory, having to do * a memset after allocation is deadly for performance. @@ -487,7 +470,7 @@ add_profile_gc_root (GCRootReport *report, void *object, int rtype, uintptr_t ex MonoNativeTlsKey thread_info_key; #ifdef HAVE_KW_THREAD -__thread SgenThreadInfo *thread_info; +__thread SgenThreadInfo *sgen_thread_info; __thread gpointer *store_remset_buffer; __thread long store_remset_buffer_index; __thread char *stack_end; @@ -848,7 +831,7 @@ static gboolean need_remove_object_for_domain (char *start, MonoDomain *domain) { if (mono_object_domain (start) == domain) { - DEBUG (4, fprintf (gc_debug_file, "Need to cleanup object %p\n", start)); + SGEN_LOG (4, "Need to cleanup object %p", start); binary_protocol_cleanup (start, (gpointer)LOAD_VTABLE (start), safe_object_get_size ((MonoObject*)start)); return TRUE; } @@ -869,8 +852,7 @@ process_object_for_domain_clearing (char *start, MonoDomain *domain) /* The server could already have been zeroed out, so we need to check for that, too. */ if (server && (!LOAD_VTABLE (server) || mono_object_domain (server) == domain)) { - DEBUG (4, fprintf (gc_debug_file, "Cleaning up remote pointer in %p to object %p\n", - start, server)); + SGEN_LOG (4, "Cleaning up remote pointer in %p to object %p", start, server); ((MonoRealProxy*)start)->unwrapped_server = NULL; } } @@ -1060,8 +1042,7 @@ mono_gc_clear_domain (MonoDomain * domain) else los_object_list = bigobj->next; bigobj = bigobj->next; - DEBUG (4, fprintf (gc_debug_file, "Freeing large object %p\n", - bigobj->data)); + SGEN_LOG (4, "Freeing large object %p", bigobj->data); sgen_los_free_object (to_free); continue; } @@ -1112,7 +1093,7 @@ sgen_drain_gray_stack (GrayQueue *queue, int max_objs) GRAY_OBJECT_DEQUEUE (queue, obj); if (!obj) return TRUE; - DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj))); + SGEN_LOG (9, "Precise gray object scan %p (%s)", obj, safe_name (obj)); scan_func (obj, queue); } } else { @@ -1123,7 +1104,7 @@ sgen_drain_gray_stack (GrayQueue *queue, int max_objs) GRAY_OBJECT_DEQUEUE (queue, obj); if (!obj) return TRUE; - DEBUG (9, fprintf (gc_debug_file, "Precise gray object scan %p (%s)\n", obj, safe_name (obj))); + SGEN_LOG (9, "Precise gray object scan %p (%s)", obj, safe_name (obj)); scan_func (obj, queue); } } while (max_objs < 0); @@ -1156,7 +1137,7 @@ pin_objects_from_addresses (GCMemSection *section, void **start, void **end, voi addr = *start; /* the range check should be reduntant */ if (addr != last && addr >= start_nursery && addr < end_nursery) { - DEBUG (5, fprintf (gc_debug_file, "Considering pinning addr %p\n", addr)); + SGEN_LOG (5, "Considering pinning addr %p", addr); /* multiple pointers to the same object */ if (addr >= last_obj && (char*)addr < (char*)last_obj + last_obj_size) { start++; @@ -1200,9 +1181,9 @@ pin_objects_from_addresses (GCMemSection *section, void **start, void **end, voi if (((MonoObject*)last_obj)->synchronisation == GINT_TO_POINTER (-1)) { /* Marks the beginning of a nursery fragment, skip */ } else { - DEBUG (8, fprintf (gc_debug_file, "Pinned try match %p (%s), size %zd\n", last_obj, safe_name (last_obj), last_obj_size)); + SGEN_LOG (8, "Pinned try match %p (%s), size %zd", last_obj, safe_name (last_obj), last_obj_size); if (addr >= search_start && (char*)addr < (char*)last_obj + last_obj_size) { - DEBUG (4, fprintf (gc_debug_file, "Pinned object %p, vtable %p (%s), count %d\n", search_start, *(void**)search_start, safe_name (search_start), count)); + SGEN_LOG (4, "Pinned object %p, vtable %p (%s), count %d\n", search_start, *(void**)search_start, safe_name (search_start), count); binary_protocol_pin (search_start, (gpointer)LOAD_VTABLE (search_start), safe_object_get_size (search_start)); if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) { int gen = sgen_ptr_in_nursery (search_start) ? GENERATION_NURSERY : GENERATION_OLD; @@ -1371,6 +1352,11 @@ static void conservatively_pin_objects_from (void **start, void **end, void *start_nursery, void *end_nursery, int pin_type) { int count = 0; + +#ifdef VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE + VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE (start, (char*)end - (char*)start); +#endif + while (start < end) { if (*start >= start_nursery && *start < end_nursery) { /* @@ -1392,18 +1378,20 @@ conservatively_pin_objects_from (void **start, void **end, void *start_nursery, */ mword addr = (mword)*start; addr &= ~(ALLOC_ALIGN - 1); - if (addr >= (mword)start_nursery && addr < (mword)end_nursery) + if (addr >= (mword)start_nursery && addr < (mword)end_nursery) { + SGEN_LOG (6, "Pinning address %p from %p", (void*)addr, start); sgen_pin_stage_ptr ((void*)addr); + count++; + } if (G_UNLIKELY (do_pin_stats)) { if (ptr_in_nursery ((void*)addr)) sgen_pin_stats_register_address ((char*)addr, pin_type); } - DEBUG (6, if (count) fprintf (gc_debug_file, "Pinning address %p from %p\n", (void*)addr, start)); - count++; } start++; } - DEBUG (7, if (count) fprintf (gc_debug_file, "found %d potential pinned heap pointers\n", count)); + if (count) + SGEN_LOG (7, "found %d potential pinned heap pointers", count); } /* @@ -1416,10 +1404,10 @@ pin_from_roots (void *start_nursery, void *end_nursery, GrayQueue *queue) { void **start_root; RootRecord *root; - DEBUG (2, fprintf (gc_debug_file, "Scanning pinned roots (%d bytes, %d/%d entries)\n", (int)roots_size, roots_hash [ROOT_TYPE_NORMAL].num_entries, roots_hash [ROOT_TYPE_PINNED].num_entries)); + SGEN_LOG (2, "Scanning pinned roots (%d bytes, %d/%d entries)", (int)roots_size, roots_hash [ROOT_TYPE_NORMAL].num_entries, roots_hash [ROOT_TYPE_PINNED].num_entries); /* objects pinned from the API are inside these roots */ SGEN_HASH_TABLE_FOREACH (&roots_hash [ROOT_TYPE_PINNED], start_root, root) { - DEBUG (6, fprintf (gc_debug_file, "Pinned roots %p-%p\n", start_root, root->end_root)); + SGEN_LOG (6, "Pinned roots %p-%p", start_root, root->end_root); conservatively_pin_objects_from (start_root, (void**)root->end_root, start_nursery, end_nursery, PIN_TYPE_OTHER); } SGEN_HASH_TABLE_FOREACH_END; /* now deal with the thread stacks @@ -1476,7 +1464,7 @@ precisely_scan_objects_from (CopyOrMarkObjectFunc copy_func, void** start_root, while (desc) { if ((desc & 1) && *start_root) { copy_func (start_root, queue); - DEBUG (9, fprintf (gc_debug_file, "Overwrote root at %p with %p\n", start_root, *start_root)); + SGEN_LOG (9, "Overwrote root at %p with %p", start_root, *start_root); sgen_drain_gray_stack (queue, -1); } desc >>= 1; @@ -1494,7 +1482,7 @@ precisely_scan_objects_from (CopyOrMarkObjectFunc copy_func, void** start_root, while (bmap) { if ((bmap & 1) && *objptr) { copy_func (objptr, queue); - DEBUG (9, fprintf (gc_debug_file, "Overwrote root at %p with %p\n", objptr, *objptr)); + SGEN_LOG (9, "Overwrote root at %p with %p", objptr, *objptr); sgen_drain_gray_stack (queue, -1); } bmap >>= 1; @@ -1558,7 +1546,7 @@ alloc_nursery (void) if (nursery_section) return; - DEBUG (2, fprintf (gc_debug_file, "Allocating nursery size: %lu\n", (unsigned long)sgen_nursery_size)); + SGEN_LOG (2, "Allocating nursery size: %lu", (unsigned long)sgen_nursery_size); /* later we will alloc a larger area for the nursery but only activate * what we need. The rest will be used as expansion if we have too many pinned * objects in the existing nursery. @@ -1577,7 +1565,7 @@ alloc_nursery (void) data = major_collector.alloc_heap (alloc_size, 0, DEFAULT_NURSERY_BITS); #endif sgen_update_heap_boundaries ((mword)data, (mword)(data + sgen_nursery_size)); - DEBUG (4, fprintf (gc_debug_file, "Expanding nursery size (%p-%p): %lu, total: %lu\n", data, data + alloc_size, (unsigned long)sgen_nursery_size, (unsigned long)mono_gc_get_heap_size ())); + SGEN_LOG (4, "Expanding nursery size (%p-%p): %lu, total: %lu", data, data + alloc_size, (unsigned long)sgen_nursery_size, (unsigned long)mono_gc_get_heap_size ()); section->data = section->next_data = data; section->size = alloc_size; section->end_data = data + sgen_nursery_size; @@ -1625,7 +1613,7 @@ mono_gc_precise_stack_mark_enabled (void) FILE * mono_gc_get_logfile (void) { - return sgen_get_logfile (); + return gc_debug_file; } static void @@ -1713,7 +1701,7 @@ report_registered_roots_by_type (int root_type) RootRecord *root; report.count = 0; SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) { - DEBUG (6, fprintf (gc_debug_file, "Precise root scan %p-%p (desc: %p)\n", start_root, root->end_root, (void*)root->root_desc)); + SGEN_LOG (6, "Precise root scan %p-%p (desc: %p)", start_root, root->end_root, (void*)root->root_desc); precisely_report_roots_from (&report, start_root, (void**)root->end_root, root->root_desc); } SGEN_HASH_TABLE_FOREACH_END; notify_gc_roots (&report); @@ -1734,7 +1722,7 @@ scan_finalizer_entries (CopyOrMarkObjectFunc copy_func, FinalizeReadyEntry *list for (fin = list; fin; fin = fin->next) { if (!fin->object) continue; - DEBUG (5, fprintf (gc_debug_file, "Scan of fin ready object: %p (%s)\n", fin->object, safe_name (fin->object))); + SGEN_LOG (5, "Scan of fin ready object: %p (%s)\n", fin->object, safe_name (fin->object)); copy_func (&fin->object, queue); } } @@ -1784,7 +1772,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue * */ sgen_drain_gray_stack (queue, -1); TV_GETTIME (atv); - DEBUG (2, fprintf (gc_debug_file, "%s generation done\n", generation_name (generation))); + SGEN_LOG (2, "%s generation done", generation_name (generation)); /* Reset bridge data, we might have lingering data from a previous collection if this is a major @@ -1841,7 +1829,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue * if (generation == GENERATION_OLD) sgen_finalize_in_range (copy_func, sgen_get_nursery_start (), sgen_get_nursery_end (), GENERATION_NURSERY, queue); /* drain the new stack that might have been created */ - DEBUG (6, fprintf (gc_debug_file, "Precise scan of gray area post fin\n")); + SGEN_LOG (6, "Precise scan of gray area post fin"); sgen_drain_gray_stack (queue, -1); /* @@ -1861,7 +1849,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue * clear_unreachable_ephemerons (copy_func, start_addr, end_addr, queue); TV_GETTIME (btv); - DEBUG (2, fprintf (gc_debug_file, "Finalize queue handling scan for %s generation: %d usecs %d ephemeron roundss\n", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds)); + SGEN_LOG (2, "Finalize queue handling scan for %s generation: %d usecs %d ephemeron rounds", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds); /* * handle disappearing links @@ -1911,7 +1899,7 @@ scan_from_registered_roots (CopyOrMarkObjectFunc copy_func, char *addr_start, ch void **start_root; RootRecord *root; SGEN_HASH_TABLE_FOREACH (&roots_hash [root_type], start_root, root) { - DEBUG (6, fprintf (gc_debug_file, "Precise root scan %p-%p (desc: %p)\n", start_root, root->end_root, (void*)root->root_desc)); + SGEN_LOG (6, "Precise root scan %p-%p (desc: %p)", start_root, root->end_root, (void*)root->root_desc); precisely_scan_objects_from (copy_func, start_root, (void**)root->end_root, addr_start, addr_end, root->root_desc, queue); } SGEN_HASH_TABLE_FOREACH_END; } @@ -2221,7 +2209,7 @@ verify_scan_starts (char *start, char *end) for (i = 0; i < nursery_section->num_scan_start; ++i) { char *addr = nursery_section->scan_starts [i]; if (addr > start && addr < end) - fprintf (gc_debug_file, "NFC-BAD SCAN START [%d] %p for obj [%p %p]\n", i, addr, start, end); + SGEN_LOG (1, "NFC-BAD SCAN START [%d] %p for obj [%p %p]", i, addr, start, end); } } @@ -2248,22 +2236,21 @@ verify_nursery (void) } if (object_is_forwarded (cur)) - fprintf (gc_debug_file, "FORWARDED OBJ %p\n", cur); + SGEN_LOG (1, "FORWARDED OBJ %p", cur); else if (object_is_pinned (cur)) - fprintf (gc_debug_file, "PINNED OBJ %p\n", cur); + SGEN_LOG (1, "PINNED OBJ %p", cur); ss = safe_object_get_size ((MonoObject*)cur); size = ALIGN_UP (safe_object_get_size ((MonoObject*)cur)); verify_scan_starts (cur, cur + size); if (do_dump_nursery_content) { if (cur > hole_start) - fprintf (gc_debug_file, "HOLE [%p %p %d]\n", hole_start, cur, (int)(cur - hole_start)); - fprintf (gc_debug_file, "OBJ [%p %p %d %d %s %d]\n", cur, cur + size, (int)size, (int)ss, sgen_safe_name ((MonoObject*)cur), (gpointer)LOAD_VTABLE (cur) == sgen_get_array_fill_vtable ()); + SGEN_LOG (1, "HOLE [%p %p %d]", hole_start, cur, (int)(cur - hole_start)); + SGEN_LOG (1, "OBJ [%p %p %d %d %s %d]", cur, cur + size, (int)size, (int)ss, sgen_safe_name ((MonoObject*)cur), (gpointer)LOAD_VTABLE (cur) == sgen_get_array_fill_vtable ()); } cur += size; hole_start = cur; } - fflush (gc_debug_file); } /* @@ -2293,7 +2280,9 @@ collect_nursery (void) verify_nursery (); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_collections0++; +#endif current_collection_generation = GENERATION_NURSERY; if (sgen_collection_is_parallel ()) @@ -2314,7 +2303,7 @@ collect_nursery (void) /* FIXME: optimize later to use the higher address where an object can be present */ nursery_next = MAX (nursery_next, sgen_get_nursery_end ()); - DEBUG (1, fprintf (gc_debug_file, "Start nursery collection %d %p-%p, size: %d\n", stat_minor_gcs, sgen_get_nursery_start (), nursery_next, (int)(nursery_next - sgen_get_nursery_start ()))); + SGEN_LOG (1, "Start nursery collection %d %p-%p, size: %d", stat_minor_gcs, sgen_get_nursery_start (), nursery_next, (int)(nursery_next - sgen_get_nursery_start ())); max_garbage_amount = nursery_next - sgen_get_nursery_start (); g_assert (nursery_section->size >= max_garbage_amount); @@ -2360,8 +2349,8 @@ collect_nursery (void) TV_GETTIME (atv); time_minor_pinning += TV_ELAPSED (btv, atv); - DEBUG (2, fprintf (gc_debug_file, "Finding pinned pointers: %d in %d usecs\n", sgen_get_pinned_count (), TV_ELAPSED (btv, atv))); - DEBUG (4, fprintf (gc_debug_file, "Start scan with %d pinned objects\n", sgen_get_pinned_count ())); + SGEN_LOG (2, "Finding pinned pointers: %d in %d usecs", sgen_get_pinned_count (), TV_ELAPSED (btv, atv)); + SGEN_LOG (4, "Start scan with %d pinned objects", sgen_get_pinned_count ()); if (whole_heap_check_before_collection) sgen_check_whole_heap (); @@ -2386,7 +2375,7 @@ collect_nursery (void) /* we don't have complete write barrier yet, so we scan all the old generation sections */ TV_GETTIME (btv); time_minor_scan_remsets += TV_ELAPSED (atv, btv); - DEBUG (2, fprintf (gc_debug_file, "Old generation scan: %d usecs\n", TV_ELAPSED (atv, btv))); + SGEN_LOG (2, "Old generation scan: %d usecs", TV_ELAPSED (atv, btv)); if (!sgen_collection_is_parallel ()) sgen_drain_gray_stack (&gray_queue, -1); @@ -2474,7 +2463,7 @@ collect_nursery (void) mono_profiler_gc_event (MONO_GC_EVENT_RECLAIM_END, 0); TV_GETTIME (btv); time_minor_fragment_creation += TV_ELAPSED (atv, btv); - DEBUG (2, fprintf (gc_debug_file, "Fragment creation: %d usecs, %lu bytes available\n", TV_ELAPSED (atv, btv), (unsigned long)fragment_total)); + SGEN_LOG (2, "Fragment creation: %d usecs, %lu bytes available", TV_ELAPSED (atv, btv), (unsigned long)fragment_total); if (consistency_check_at_minor_collection) sgen_check_major_refs (); @@ -2490,7 +2479,7 @@ collect_nursery (void) /* prepare the pin queue for the next collection */ sgen_finish_pinning (); if (fin_ready_list || critical_fin_list) { - DEBUG (4, fprintf (gc_debug_file, "Finalizer-thread wakeup: ready %d\n", num_ready_finalizers)); + SGEN_LOG (4, "Finalizer-thread wakeup: ready %d", num_ready_finalizers); mono_gc_finalize_notify (); } sgen_pin_stats_reset (); @@ -2537,7 +2526,9 @@ major_do_collection (const char *reason) MONO_GC_BEGIN (GENERATION_OLD); current_collection_generation = GENERATION_OLD; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_collections1++; +#endif current_object_ops = major_collector.major_ops; @@ -2556,7 +2547,7 @@ major_do_collection (const char *reason) sgen_nursery_alloc_prepare_for_major (); degraded_mode = 0; - DEBUG (1, fprintf (gc_debug_file, "Start major collection %d\n", stat_major_gcs)); + SGEN_LOG (1, "Start major collection %d", stat_major_gcs); stat_major_gcs++; gc_stats.major_gc_count ++; @@ -2597,7 +2588,7 @@ major_do_collection (const char *reason) TV_GETTIME (atv); sgen_init_pinning (); - DEBUG (6, fprintf (gc_debug_file, "Collecting pinned addresses\n")); + SGEN_LOG (6, "Collecting pinned addresses"); pin_from_roots ((void*)lowest_heap_address, (void*)highest_heap_address, WORKERS_DISTRIBUTE_GRAY_QUEUE); sgen_optimize_pin_queue (0); @@ -2613,12 +2604,12 @@ major_do_collection (const char *reason) * The second, destructive, pass is to reduce the section * areas to pointers to the actually pinned objects. */ - DEBUG (6, fprintf (gc_debug_file, "Pinning from sections\n")); + SGEN_LOG (6, "Pinning from sections"); /* first pass for the sections */ sgen_find_section_pin_queue_start_end (nursery_section); major_collector.find_pin_queue_start_ends (WORKERS_DISTRIBUTE_GRAY_QUEUE); /* identify possible pointers to the insize of large objects */ - DEBUG (6, fprintf (gc_debug_file, "Pinning from large objects\n")); + SGEN_LOG (6, "Pinning from large objects"); for (bigobj = los_object_list; bigobj; bigobj = bigobj->next) { int dummy; gboolean profile_roots = mono_profiler_get_events () & MONO_PROFILE_GC_ROOTS; @@ -2635,7 +2626,7 @@ major_do_collection (const char *reason) GRAY_OBJECT_ENQUEUE (WORKERS_DISTRIBUTE_GRAY_QUEUE, bigobj->data); if (G_UNLIKELY (do_pin_stats)) sgen_pin_stats_register_object ((char*) bigobj->data, safe_object_get_size ((MonoObject*) bigobj->data)); - DEBUG (6, fprintf (gc_debug_file, "Marked large object %p (%s) size: %lu from roots\n", bigobj->data, safe_name (bigobj->data), (unsigned long)bigobj->size)); + SGEN_LOG (6, "Marked large object %p (%s) size: %lu from roots", bigobj->data, safe_name (bigobj->data), (unsigned long)bigobj->size); if (profile_roots) add_profile_gc_root (&report, bigobj->data, MONO_PROFILE_GC_ROOT_PINNING | MONO_PROFILE_GC_ROOT_MISC, 0); @@ -2650,8 +2641,8 @@ major_do_collection (const char *reason) TV_GETTIME (btv); time_major_pinning += TV_ELAPSED (atv, btv); - DEBUG (2, fprintf (gc_debug_file, "Finding pinned pointers: %d in %d usecs\n", sgen_get_pinned_count (), TV_ELAPSED (atv, btv))); - DEBUG (4, fprintf (gc_debug_file, "Start scan with %d pinned objects\n", sgen_get_pinned_count ())); + SGEN_LOG (2, "Finding pinned pointers: %d in %d usecs", sgen_get_pinned_count (), TV_ELAPSED (atv, btv)); + SGEN_LOG (4, "Start scan with %d pinned objects", sgen_get_pinned_count ()); major_collector.init_to_space (); @@ -2706,7 +2697,7 @@ major_do_collection (const char *reason) TV_GETTIME (atv); time_major_scan_finalized += TV_ELAPSED (btv, atv); - DEBUG (2, fprintf (gc_debug_file, "Root scan: %d usecs\n", TV_ELAPSED (btv, atv))); + SGEN_LOG (2, "Root scan: %d usecs", TV_ELAPSED (btv, atv)); TV_GETTIME (btv); time_major_scan_big_objects += TV_ELAPSED (atv, btv); @@ -2808,7 +2799,7 @@ major_do_collection (const char *reason) sgen_finish_pinning (); if (fin_ready_list || critical_fin_list) { - DEBUG (4, fprintf (gc_debug_file, "Finalizer-thread wakeup: ready %d\n", num_ready_finalizers)); + SGEN_LOG (4, "Finalizer-thread wakeup: ready %d", num_ready_finalizers); mono_gc_finalize_notify (); } sgen_pin_stats_reset (); @@ -2924,12 +2915,12 @@ sgen_perform_collection (size_t requested_size, int generation_to_collect, const mono_profiler_gc_event (MONO_GC_EVENT_END, overflow_generation_to_collect); } - DEBUG (2, fprintf (gc_debug_file, "Heap size: %lu, LOS size: %lu\n", (unsigned long)mono_gc_get_heap_size (), (unsigned long)los_memory_usage)); + SGEN_LOG (2, "Heap size: %lu, LOS size: %lu", (unsigned long)mono_gc_get_heap_size (), (unsigned long)los_memory_usage); /* this also sets the proper pointers for the next allocation */ if (generation_to_collect == GENERATION_NURSERY && !sgen_can_alloc_size (requested_size)) { /* TypeBuilder and MonoMethod are killing mcs with fragmentation */ - DEBUG (1, fprintf (gc_debug_file, "nursery collection didn't find enough room for %zd alloc (%d pinned)\n", requested_size, sgen_get_pinned_count ())); + SGEN_LOG (1, "nursery collection didn't find enough room for %zd alloc (%d pinned)", requested_size, sgen_get_pinned_count ()); sgen_dump_pin_queue (); degraded_mode = 1; } @@ -3079,7 +3070,7 @@ clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char if (!object_is_reachable (object, start, end)) { EphemeronLinkNode *tmp = current; - DEBUG (5, fprintf (gc_debug_file, "Dead Ephemeron array at %p\n", object)); + SGEN_LOG (5, "Dead Ephemeron array at %p", object); if (prev) prev->next = current->next; @@ -3099,7 +3090,7 @@ clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char /*The array was promoted, add global remsets for key/values left behind in nursery.*/ was_promoted = was_in_nursery && !ptr_in_nursery (object); - DEBUG (5, fprintf (gc_debug_file, "Clearing unreachable entries for ephemeron array at %p\n", object)); + SGEN_LOG (5, "Clearing unreachable entries for ephemeron array at %p", object); array = (MonoArray*)object; cur = mono_array_addr (array, Ephemeron, 0); @@ -3112,9 +3103,9 @@ clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char if (!key || key == tombstone) continue; - DEBUG (5, fprintf (gc_debug_file, "[%td] key %p (%s) value %p (%s)\n", cur - mono_array_addr (array, Ephemeron, 0), + SGEN_LOG (5, "[%td] key %p (%s) value %p (%s)", cur - mono_array_addr (array, Ephemeron, 0), key, object_is_reachable (key, start, end) ? "reachable" : "unreachable", - cur->value, cur->value && object_is_reachable (cur->value, start, end) ? "reachable" : "unreachable")); + cur->value, cur->value && object_is_reachable (cur->value, start, end) ? "reachable" : "unreachable"); if (!object_is_reachable (key, start, end)) { cur->key = tombstone; @@ -3124,11 +3115,11 @@ clear_unreachable_ephemerons (CopyOrMarkObjectFunc copy_func, char *start, char if (was_promoted) { if (ptr_in_nursery (key)) {/*key was not promoted*/ - DEBUG (5, fprintf (gc_debug_file, "\tAdded remset to key %p\n", key)); + SGEN_LOG (5, "\tAdded remset to key %p", key); sgen_add_to_global_remset (&cur->key); } if (ptr_in_nursery (cur->value)) {/*value was not promoted*/ - DEBUG (5, fprintf (gc_debug_file, "\tAdded remset to value %p\n", cur->value)); + SGEN_LOG (5, "\tAdded remset to value %p", cur->value); sgen_add_to_global_remset (&cur->value); } } @@ -3150,7 +3141,7 @@ mark_ephemerons_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end for (current = ephemeron_list; current; current = current->next) { char *object = current->array; - DEBUG (5, fprintf (gc_debug_file, "Ephemeron array at %p\n", object)); + SGEN_LOG (5, "Ephemeron array at %p", object); /* For now we process all ephemerons during all collections. @@ -3164,7 +3155,7 @@ mark_ephemerons_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end /*It has to be alive*/ if (!object_is_reachable (object, start, end)) { - DEBUG (5, fprintf (gc_debug_file, "\tnot reachable\n")); + SGEN_LOG (5, "\tnot reachable"); continue; } @@ -3181,9 +3172,9 @@ mark_ephemerons_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end if (!key || key == tombstone) continue; - DEBUG (5, fprintf (gc_debug_file, "[%td] key %p (%s) value %p (%s)\n", cur - mono_array_addr (array, Ephemeron, 0), + SGEN_LOG (5, "[%td] key %p (%s) value %p (%s)", cur - mono_array_addr (array, Ephemeron, 0), key, object_is_reachable (key, start, end) ? "reachable" : "unreachable", - cur->value, cur->value && object_is_reachable (cur->value, start, end) ? "reachable" : "unreachable")); + cur->value, cur->value && object_is_reachable (cur->value, start, end) ? "reachable" : "unreachable"); if (object_is_reachable (key, start, end)) { char *value = cur->value; @@ -3198,7 +3189,7 @@ mark_ephemerons_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end } } - DEBUG (5, fprintf (gc_debug_file, "Ephemeron run finished. Is it done %d\n", nothing_marked)); + SGEN_LOG (5, "Ephemeron run finished. Is it done %d", nothing_marked); return nothing_marked; } @@ -3247,7 +3238,7 @@ mono_gc_invoke_finalizers (void) num_ready_finalizers--; obj = entry->object; entry->object = NULL; - DEBUG (7, fprintf (gc_debug_file, "Finalizing object %p (%s)\n", obj, safe_name (obj))); + SGEN_LOG (7, "Finalizing object %p (%s)", obj, safe_name (obj)); } UNLOCK_GC; @@ -3308,7 +3299,7 @@ mono_gc_register_root_inner (char *start, size_t size, void *descr, int root_typ sgen_hash_table_replace (&roots_hash [root_type], start, &new_root, NULL); roots_size += size; - DEBUG (3, fprintf (gc_debug_file, "Added root for range: %p-%p, descr: %p (%d/%d bytes)\n", start, new_root.end_root, descr, (int)size, (int)roots_size)); + SGEN_LOG (3, "Added root for range: %p-%p, descr: %p (%d/%d bytes)", start, new_root.end_root, descr, (int)size, (int)roots_size); UNLOCK_GC; return TRUE; @@ -3403,20 +3394,20 @@ scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, Gray FOREACH_THREAD (info) { if (info->skip) { - DEBUG (3, fprintf (gc_debug_file, "Skipping dead thread %p, range: %p-%p, size: %td\n", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start)); + SGEN_LOG (3, "Skipping dead thread %p, range: %p-%p, size: %td", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start); continue; } if (info->gc_disabled) { - DEBUG (3, fprintf (gc_debug_file, "GC disabled for thread %p, range: %p-%p, size: %td\n", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start)); + SGEN_LOG (3, "GC disabled for thread %p, range: %p-%p, size: %td", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start); continue; } if (!info->joined_stw) { - DEBUG (3, fprintf (gc_debug_file, "Skipping thread not seen in STW %p, range: %p-%p, size: %td\n", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start)); + SGEN_LOG (3, "Skipping thread not seen in STW %p, range: %p-%p, size: %td", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start); continue; } - DEBUG (3, fprintf (gc_debug_file, "Scanning thread %p, range: %p-%p, size: %td, pinned=%d\n", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start, sgen_get_pinned_count ())); + SGEN_LOG (3, "Scanning thread %p, range: %p-%p, size: %td, pinned=%d", info, info->stack_start, info->stack_end, (char*)info->stack_end - (char*)info->stack_start, sgen_get_pinned_count ()); if (!info->thread_is_dying) { if (gc_callbacks.thread_mark_func && !conservative_stack_mark) { UserCopyOrMarkData data = { NULL, queue }; @@ -3465,7 +3456,7 @@ sgen_thread_register (SgenThreadInfo* info, void *addr) g_assert (!mono_native_tls_get_value (thread_info_key)); mono_native_tls_set_value (thread_info_key, info); #else - thread_info = info; + sgen_thread_info = info; #endif #if !defined(__MACH__) @@ -3527,7 +3518,7 @@ sgen_thread_register (SgenThreadInfo* info, void *addr) if (remset.register_thread) remset.register_thread (info); - DEBUG (3, fprintf (gc_debug_file, "registered thread %p (%p) stack end %p\n", info, (gpointer)mono_thread_info_get_tid (info), info->stack_end)); + SGEN_LOG (3, "registered thread %p (%p) stack end %p", info, (gpointer)mono_thread_info_get_tid (info), info->stack_end); if (gc_callbacks.thread_attach_func) info->runtime_data = gc_callbacks.thread_attach_func (); @@ -3588,7 +3579,7 @@ sgen_thread_unregister (SgenThreadInfo *p) #endif binary_protocol_thread_unregister ((gpointer)mono_thread_info_get_tid (p)); - DEBUG (3, fprintf (gc_debug_file, "unregister thread %p (%p)\n", p, (gpointer)mono_thread_info_get_tid (p))); + SGEN_LOG (3, "unregister thread %p (%p)", p, (gpointer)mono_thread_info_get_tid (p)); if (gc_callbacks.thread_detach_func) { gc_callbacks.thread_detach_func (p->runtime_data); @@ -3687,7 +3678,7 @@ mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* val *(void**)field_ptr = value; return; } - DEBUG (8, fprintf (gc_debug_file, "Adding remset at %p\n", field_ptr)); + SGEN_LOG (8, "Adding remset at %p", field_ptr); if (value) binary_protocol_wbarrier (field_ptr, value, value->vtable); @@ -3702,7 +3693,7 @@ mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* va *(void**)slot_ptr = value; return; } - DEBUG (8, fprintf (gc_debug_file, "Adding remset at %p\n", slot_ptr)); + SGEN_LOG (8, "Adding remset at %p", slot_ptr); if (value) binary_protocol_wbarrier (slot_ptr, value, value->vtable); @@ -3799,11 +3790,11 @@ mono_gc_wbarrier_generic_nostore (gpointer ptr) binary_protocol_wbarrier (ptr, *(gpointer*)ptr, (gpointer)LOAD_VTABLE (*(gpointer*)ptr)); if (ptr_in_nursery (ptr) || ptr_on_stack (ptr) || !ptr_in_nursery (*(gpointer*)ptr)) { - DEBUG (8, fprintf (gc_debug_file, "Skipping remset at %p\n", ptr)); + SGEN_LOG (8, "Skipping remset at %p", ptr); return; } - DEBUG (8, fprintf (gc_debug_file, "Adding remset at %p\n", ptr)); + SGEN_LOG (8, "Adding remset at %p", ptr); remset.wbarrier_generic_nostore (ptr); } @@ -3811,7 +3802,7 @@ mono_gc_wbarrier_generic_nostore (gpointer ptr) void mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value) { - DEBUG (8, fprintf (gc_debug_file, "Wbarrier store at %p to %p (%s)\n", ptr, value, value ? safe_name (value) : "null")); + SGEN_LOG (8, "Wbarrier store at %p to %p (%s)", ptr, value, value ? safe_name (value) : "null"); *(void**)ptr = value; if (ptr_in_nursery (value)) mono_gc_wbarrier_generic_nostore (ptr); @@ -3859,7 +3850,7 @@ mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass * HEAVY_STAT (++stat_wbarrier_value_copy); g_assert (klass->valuetype); - DEBUG (8, fprintf (gc_debug_file, "Adding value remset at %p, count %d, descr %p for class %s (%p)\n", dest, count, klass->gc_descr, klass->name, klass)); + SGEN_LOG (8, "Adding value remset at %p, count %d, descr %p for class %s (%p)", dest, count, klass->gc_descr, klass->name, klass); if (ptr_in_nursery (dest) || ptr_on_stack (dest) || !SGEN_CLASS_HAS_REFERENCES (klass)) { size_t element_size = mono_class_value_size (klass, NULL); @@ -4132,7 +4123,7 @@ mono_gc_ephemeron_array_add (MonoObject *obj) node->next = ephemeron_list; ephemeron_list = node; - DEBUG (5, fprintf (gc_debug_file, "Registered ephemeron array %p\n", obj)); + SGEN_LOG (5, "Registered ephemeron array %p", obj); UNLOCK_GC; return TRUE; @@ -4459,7 +4450,7 @@ mono_gc_base_init (void) fprintf (stderr, " max-heap-size=N (where N is an integer, possibly with a k, m or a g suffix)\n"); fprintf (stderr, " soft-heap-limit=n (where N is an integer, possibly with a k, m or a g suffix)\n"); fprintf (stderr, " nursery-size=N (where N is an integer, possibly with a k, m or a g suffix)\n"); - fprintf (stderr, " major=COLLECTOR (where COLLECTOR is `marksweep', `marksweep-par' or `copying')\n"); + fprintf (stderr, " major=COLLECTOR (where COLLECTOR is `marksweep', `marksweep-par', 'marksweep-fixed', 'marksweep-fixed-par' or `copying')\n"); fprintf (stderr, " minor=COLLECTOR (where COLLECTOR is `simple' or `split')\n"); fprintf (stderr, " wbarrier=WBARRIER (where WBARRIER is `remset' or `cardtable')\n"); fprintf (stderr, " stack-mark=MARK-METHOD (where MARK-METHOD is 'precise' or 'conservative')\n"); @@ -4909,25 +4900,6 @@ mono_gc_is_disabled (void) return FALSE; } -void -sgen_debug_printf (int level, const char *format, ...) -{ - va_list ap; - - if (level > gc_debug_level) - return; - - va_start (ap, format); - vfprintf (gc_debug_file, format, ap); - va_end (ap); -} - -FILE* -sgen_get_logfile (void) -{ - return gc_debug_file; -} - #ifdef HOST_WIN32 BOOL APIENTRY mono_gc_dllmain (HMODULE module_handle, DWORD reason, LPVOID reserved) { diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index 0a946d0b2af..c17bd2fcf5a 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -1,26 +1,23 @@ /* + * sgen-gc.c: Simple generational GC. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MONO_SGENGC_H__ #define __MONO_SGENGC_H__ @@ -41,6 +38,7 @@ typedef struct _SgenThreadInfo SgenThreadInfo; #include #include #include +#include #include #include #include @@ -242,7 +240,27 @@ extern long long stat_objects_copied_major; #define HEAVY_STAT(x) #endif -#define DEBUG(level,a) do {if (G_UNLIKELY ((level) <= SGEN_MAX_DEBUG_LEVEL && (level) <= gc_debug_level)) { a; fflush (gc_debug_file); } } while (0) +#define SGEN_ASSERT(level, a, ...) do { \ + if (G_UNLIKELY ((level) <= SGEN_MAX_ASSERT_LEVEL && !(a))) { \ + g_error (__VA_ARGS__); \ +} } while (0) + + +#define SGEN_LOG(level, format, ...) do { \ + if (G_UNLIKELY ((level) <= SGEN_MAX_DEBUG_LEVEL && (level) <= gc_debug_level)) { \ + mono_gc_printf (gc_debug_file, format, ##__VA_ARGS__); \ +} } while (0) + +#define SGEN_COND_LOG(level, cond, format, ...) do { \ + if (G_UNLIKELY ((level) <= SGEN_MAX_DEBUG_LEVEL && (level) <= gc_debug_level)) { \ + if (cond) \ + mono_gc_printf (gc_debug_file, format, ##__VA_ARGS__); \ +} } while (0) + +#define SGEN_LOG_DO(level, fun) do { \ + if (G_UNLIKELY ((level) <= SGEN_MAX_DEBUG_LEVEL && (level) <= gc_debug_level)) { \ + fun; \ +} } while (0) extern int gc_debug_level; extern FILE* gc_debug_file; @@ -501,9 +519,6 @@ void sgen_free_internal_dynamic (void *addr, size_t size, int type) MONO_INTERNA void* sgen_alloc_pinned (SgenPinnedAllocator *allocator, size_t size) MONO_INTERNAL; void sgen_free_pinned (SgenPinnedAllocator *allocator, void *addr, size_t size) MONO_INTERNAL; - -void sgen_debug_printf (int level, const char *format, ...) MONO_INTERNAL; - gboolean sgen_parse_environment_string_extract_number (const char *str, glong *out) MONO_INTERNAL; void sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc callback, void *callback_data) MONO_INTERNAL; @@ -591,8 +606,8 @@ sgen_nursery_is_to_space (char *object) int byte = idx / 8; int bit = idx & 0x7; - DEBUG (4, g_assert (sgen_ptr_in_nursery (object))); - DEBUG (4, g_assert (byte < sgen_space_bitmap_size)); + SGEN_ASSERT (4, sgen_ptr_in_nursery (object), "object %p is not in nursery [%p - %p]", object, sgen_get_nursery_start (), sgen_get_nursery_end ()); + SGEN_ASSERT (4, byte < sgen_space_bitmap_size, "byte index %d out of range", byte, sgen_space_bitmap_size); return (sgen_space_bitmap [byte] & (1 << bit)) != 0; } @@ -892,7 +907,6 @@ void sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data) MO void sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback) MONO_INTERNAL; void sgen_los_scan_card_table (SgenGrayQueue *queue) MONO_INTERNAL; void sgen_major_collector_scan_card_table (SgenGrayQueue *queue) MONO_INTERNAL; -FILE *sgen_get_logfile (void) MONO_INTERNAL; gboolean sgen_los_is_valid_object (char *object) MONO_INTERNAL; gboolean mono_sgen_los_describe_pointer (char *ptr) MONO_INTERNAL; @@ -923,7 +937,7 @@ char* sgen_par_alloc_for_promotion (char *obj, size_t objsize, gboolean has_refe extern MonoNativeTlsKey thread_info_key; #ifdef HAVE_KW_THREAD -extern __thread SgenThreadInfo *thread_info; +extern __thread SgenThreadInfo *sgen_thread_info; extern __thread gpointer *store_remset_buffer; extern __thread long store_remset_buffer_index; extern __thread char *stack_end; @@ -935,7 +949,7 @@ extern __thread long *store_remset_buffer_index_addr; #define REMEMBERED_SET remembered_set #define STORE_REMSET_BUFFER store_remset_buffer #define STORE_REMSET_BUFFER_INDEX store_remset_buffer_index -#define IN_CRITICAL_REGION thread_info->in_critical_region +#define IN_CRITICAL_REGION sgen_thread_info->in_critical_region #else #define TLAB_ACCESS_INIT SgenThreadInfo *__thread_info__ = mono_native_tls_get_value (thread_info_key) #define REMEMBERED_SET (__thread_info__->remset) @@ -947,7 +961,7 @@ extern __thread long *store_remset_buffer_index_addr; #ifndef DISABLE_CRITICAL_REGION #ifdef HAVE_KW_THREAD -#define IN_CRITICAL_REGION thread_info->in_critical_region +#define IN_CRITICAL_REGION sgen_thread_info->in_critical_region #else #define IN_CRITICAL_REGION (__thread_info__->in_critical_region) #endif diff --git a/mono/metadata/sgen-gray.c b/mono/metadata/sgen-gray.c index b1459bca2aa..cb89c3bfda1 100644 --- a/mono/metadata/sgen-gray.c +++ b/mono/metadata/sgen-gray.c @@ -1,25 +1,22 @@ /* + * sgen-gray.c: Gray queue management. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #ifdef HAVE_SGEN_GC @@ -68,14 +65,14 @@ sgen_gray_object_free_queue_section (GrayQueueSection *section) void sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj) { - DEBUG (9, g_assert (obj)); + SGEN_ASSERT (9, obj, "enqueueing a null object"); //sgen_check_objref (obj); if (G_UNLIKELY (!queue->first || queue->first->end == SGEN_GRAY_QUEUE_SECTION_SIZE)) sgen_gray_object_alloc_queue_section (queue); - DEBUG (9, g_assert (queue->first && queue->first->end < SGEN_GRAY_QUEUE_SECTION_SIZE)); + SGEN_ASSERT (9, queue->first->end < SGEN_GRAY_QUEUE_SECTION_SIZE, "gray queue %p overflow, first %p, end %d", queue, queue->first, queue->first->end); queue->first->objects [queue->first->end++] = obj; - DEBUG (9, ++queue->balance); + SGEN_LOG_DO (9, ++queue->balance); } char* @@ -86,7 +83,7 @@ sgen_gray_object_dequeue (SgenGrayQueue *queue) if (sgen_gray_object_queue_is_empty (queue)) return NULL; - DEBUG (9, g_assert (queue->first->end)); + SGEN_ASSERT (9, queue->first->end, "gray queue %p underflow, first %p, end %d", queue, queue->first, queue->first->end); obj = queue->first->objects [--queue->first->end]; @@ -97,7 +94,7 @@ sgen_gray_object_dequeue (SgenGrayQueue *queue) queue->free_list = section; } - DEBUG (9, --queue->balance); + SGEN_LOG_DO (9, --queue->balance); return obj; } @@ -132,7 +129,7 @@ sgen_gray_object_queue_init (SgenGrayQueue *queue) int i; g_assert (sgen_gray_object_queue_is_empty (queue)); - DEBUG (9, g_assert (queue->balance == 0)); + SGEN_ASSERT (9, queue->balance == 0, "unbalanced queue on init %d", queue->balance); /* Free the extra sections allocated during the last collection */ i = 0; diff --git a/mono/metadata/sgen-los.c b/mono/metadata/sgen-los.c index f794d0b2912..157009ca2de 100644 --- a/mono/metadata/sgen-los.c +++ b/mono/metadata/sgen-los.c @@ -1,5 +1,5 @@ /* - * sgen-los.c: Simple generational GC. + * sgen-los.c: Large objects space. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -11,38 +11,22 @@ * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2004 by Hewlett-Packard Company. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -308,7 +292,7 @@ sgen_los_free_object (LOSObject *obj) { #ifndef LOS_DUMMY size_t size = obj->size; - DEBUG (4, fprintf (gc_debug_file, "Freed large object %p, size %lu\n", obj->data, (unsigned long)obj->size)); + SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)obj->size); binary_protocol_empty (obj->data, obj->size); los_memory_usage -= size; @@ -394,7 +378,7 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) los_object_list = obj; los_memory_usage += size; los_num_objects++; - DEBUG (4, fprintf (gc_debug_file, "Allocated large object %p, vtable: %p (%s), size: %zd\n", obj->data, vtable, vtable->klass->name, size)); + SGEN_LOG (4, "Allocated large object %p, vtable: %p (%s), size: %zd", obj->data, vtable, vtable->klass->name, size); binary_protocol_alloc (obj->data, vtable, size); #ifdef LOS_CONSISTENCY_CHECK @@ -509,22 +493,23 @@ mono_sgen_los_describe_pointer (char *ptr) for (obj = los_object_list; obj; obj = obj->next) { MonoVTable *vtable; + const char *los_kind; if (obj->data > ptr || obj->data + obj->size <= ptr) continue; if (obj->size > LOS_SECTION_OBJECT_LIMIT) - fprintf (gc_debug_file, "huge-los-ptr "); + los_kind = "huge-los-ptr "; else - fprintf (gc_debug_file, "los-ptr "); + los_kind = "los-ptr "; vtable = (MonoVTable*)SGEN_LOAD_VTABLE (obj->data); if (obj->data == ptr) - fprintf (gc_debug_file, "(object %s.%s size %d)", - vtable->klass->name_space, vtable->klass->name, (int)obj->size); + SGEN_LOG (1, "%s (object %s.%s size %d)", + los_kind, vtable->klass->name_space, vtable->klass->name, (int)obj->size); else - fprintf (gc_debug_file, "(interior-ptr offset %td of %p (%s.%s) size %d)", - ptr - obj->data, obj->data, + SGEN_LOG (1, "%s (interior-ptr offset %td of %p (%s.%s) size %d)", + los_kind, ptr - obj->data, obj->data, vtable->klass->name_space, vtable->klass->name, (int)obj->size); return TRUE; diff --git a/mono/metadata/sgen-major-copy-object.h b/mono/metadata/sgen-major-copy-object.h index 0575743f317..e912be704c2 100644 --- a/mono/metadata/sgen-major-copy-object.h +++ b/mono/metadata/sgen-major-copy-object.h @@ -1,25 +1,22 @@ /* + * sgen-major-copy-object.h: Object copying in the major collectors. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define collector_pin_object(obj, queue) do { \ @@ -31,8 +28,8 @@ } \ } while (0) -#define collector_serial_alloc_for_promotion sgen_minor_collector.alloc_for_promotion -#define collector_parallel_alloc_for_promotion sgen_minor_collector.par_alloc_for_promotion +#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION sgen_minor_collector.alloc_for_promotion +#define COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION sgen_minor_collector.par_alloc_for_promotion #include "sgen-copy-object.h" diff --git a/mono/metadata/sgen-major-copying.c b/mono/metadata/sgen-major-copying.c index e52c26903c3..2b44b47398e 100644 --- a/mono/metadata/sgen-major-copying.c +++ b/mono/metadata/sgen-major-copying.c @@ -1,10 +1,13 @@ /* - * sgen-major-copying.c: Simple generational GC. + * sgen-major-copying.c: The copying major collector. * * Author: * Paolo Molaro (lupus@ximian.com) * * Copyright 2005-2010 Novell, Inc (http://www.novell.com) + * Copyright 2001-2003 Ximian, Inc + * Copyright 2003-2010 Novell, Inc. + * Copyright (C) 2012 Xamarin Inc * * Thread start/stop adapted from Boehm's GC: * Copyright (c) 1994 by Xerox Corporation. All rights reserved. @@ -12,37 +15,18 @@ * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2004 by Hewlett-Packard Company. All rights reserved. * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * - * Copyright 2001-2003 Ximian, Inc - * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -59,6 +43,8 @@ #include "metadata/profiler-private.h" #include "metadata/sgen-memory-governor.h" +#ifndef DISABLE_SGEN_MAJOR_COPYING + #define MAJOR_SECTION_SIZE SGEN_PINNED_CHUNK_SIZE #define BLOCK_FOR_OBJECT(o) SGEN_PINNED_CHUNK_FOR_PTR ((o)) #define MAJOR_SECTION_FOR_OBJECT(o) ((GCMemSection*)BLOCK_FOR_OBJECT ((o))) @@ -135,7 +121,7 @@ alloc_major_section (void) section->size = MAJOR_SECTION_SIZE - SGEN_SIZEOF_GC_MEM_SECTION; section->end_data = section->data + section->size; sgen_update_heap_boundaries ((mword)section->data, (mword)section->end_data); - DEBUG (3, fprintf (gc_debug_file, "New major heap section: (%p-%p), total: %lld\n", section->data, section->end_data, (long long int)mono_gc_get_heap_size ())); + SGEN_LOG (3, "New major heap section: (%p-%p), total: %lld", section->data, section->end_data, (long long int)mono_gc_get_heap_size ()); scan_starts = (section->size + SGEN_SCAN_START_SIZE - 1) / SGEN_SCAN_START_SIZE; section->scan_starts = sgen_alloc_internal_dynamic (sizeof (char*) * scan_starts, INTERNAL_MEM_SCAN_STARTS, TRUE); section->num_scan_start = scan_starts; @@ -154,7 +140,7 @@ alloc_major_section (void) static void free_major_section (GCMemSection *section) { - DEBUG (3, fprintf (gc_debug_file, "Freed major section %p (%p-%p)\n", section, section->data, section->end_data)); + SGEN_LOG (3, "Freed major section %p (%p-%p)", section, section->data, section->end_data); sgen_free_internal_dynamic (section->scan_starts, (section->size + SGEN_SCAN_START_SIZE - 1) / SGEN_SCAN_START_SIZE * sizeof (char*), INTERNAL_MEM_SCAN_STARTS); sgen_free_os_memory (section, MAJOR_SECTION_SIZE, SGEN_ALLOC_HEAP); @@ -199,10 +185,10 @@ major_alloc_object (int size, gboolean has_references) if (dest + size > to_space_top) { to_space_expand (); (dest) = to_space_bumper; - DEBUG (8, g_assert (dest + size <= to_space_top)); + SGEN_ASSERT (8, dest + size <= to_space_top, "space allocation overflow dest %p size %d to-space-top %p", dest, size, to_space_top); } to_space_bumper += size; - DEBUG (8, g_assert (to_space_bumper <= to_space_top)); + SGEN_ASSERT (8, to_space_bumper <= to_space_top, "to-space-bumper %p overflow to-space-top %p", to_space_bumper, to_space_top); to_space_section->scan_starts [(dest - (char*)to_space_section->data)/SGEN_SCAN_START_SIZE] = dest; return dest; } @@ -275,7 +261,7 @@ major_alloc_degraded (MonoVTable *vtable, size_t size) sgen_register_major_sections_alloced (1); } section->next_data += size; - DEBUG (3, fprintf (gc_debug_file, "Allocated (degraded) object %p, vtable: %p (%s), size: %zd in section %p\n", p, vtable, vtable->klass->name, size, section)); + SGEN_LOG (3, "Allocated (degraded) object %p, vtable: %p (%s), size: %zd in section %p", p, vtable, vtable->klass->name, size, section); *p = vtable; return p; } @@ -295,11 +281,11 @@ major_copy_or_mark_object (void **obj_slot, SgenGrayQueue *queue) char *obj = *obj_slot; mword objsize; - DEBUG (9, g_assert (current_collection_generation == GENERATION_OLD)); + SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); HEAVY_STAT (++stat_copy_object_called_major); - DEBUG (9, fprintf (gc_debug_file, "Precise copy of %p from %p", obj, obj_slot)); + SGEN_LOG (9, "Precise copy of %p from %p", obj, obj_slot); /* * obj must belong to one of: @@ -327,23 +313,26 @@ major_copy_or_mark_object (void **obj_slot, SgenGrayQueue *queue) */ if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { - DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr)); - DEBUG (9, fprintf (gc_debug_file, " (already forwarded to %p)\n", forwarded)); + SGEN_ASSERT (9, (*(MonoVTable**)SGEN_LOAD_VTABLE (obj))->gc_descr, "forwarded object %p has no gc descriptor", forwarded); + SGEN_LOG (9, " (already forwarded to %p)", forwarded); HEAVY_STAT (++stat_major_copy_object_failed_forwarded); *obj_slot = forwarded; return; } if (SGEN_OBJECT_IS_PINNED (obj)) { - DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr)); - DEBUG (9, fprintf (gc_debug_file, " (pinned, no change)\n")); + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "pinned object %p has no gc descriptor", obj); + SGEN_LOG (9, " (pinned, no change)"); HEAVY_STAT (++stat_major_copy_object_failed_pinned); return; } if (ptr_in_nursery (obj)) { /* A To Space object is already on its final destination for the current collection. */ - if (sgen_nursery_is_to_space (obj)) + if (sgen_nursery_is_to_space (obj)) { + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "to space object %p has no gc descriptor", obj); + SGEN_LOG (9, " (tospace, no change)"); return; + } goto copy; } @@ -368,7 +357,7 @@ major_copy_or_mark_object (void **obj_slot, SgenGrayQueue *queue) if (G_UNLIKELY (objsize > SGEN_MAX_SMALL_OBJ_SIZE || obj_is_from_pinned_alloc (obj))) { if (SGEN_OBJECT_IS_PINNED (obj)) return; - DEBUG (9, fprintf (gc_debug_file, " (marked LOS/Pinned %p (%s), size: %td)\n", obj, sgen_safe_name (obj), objsize)); + SGEN_LOG (9, " (marked LOS/Pinned %p (%s), size: %td)", obj, sgen_safe_name (obj), objsize); binary_protocol_pin (obj, (gpointer)SGEN_LOAD_VTABLE (obj), sgen_safe_object_get_size ((MonoObject*)obj)); SGEN_PIN_OBJECT (obj); GRAY_OBJECT_ENQUEUE (queue, obj); @@ -382,8 +371,8 @@ major_copy_or_mark_object (void **obj_slot, SgenGrayQueue *queue) * not (4). */ if (MAJOR_OBJ_IS_IN_TO_SPACE (obj)) { - DEBUG (9, g_assert (objsize <= SGEN_MAX_SMALL_OBJ_SIZE)); - DEBUG (9, fprintf (gc_debug_file, " (already copied)\n")); + SGEN_ASSERT (9, objsize <= SGEN_MAX_SMALL_OBJ_SIZE, "object %p in to space is too big, size %d", objsize); + SGEN_LOG (9, " (already copied)"); HEAVY_STAT (++stat_major_copy_object_failed_to_space); return; } @@ -442,9 +431,9 @@ sweep_pinned_objects_callback (char *ptr, size_t size, void *data) { if (SGEN_OBJECT_IS_PINNED (ptr)) { SGEN_UNPIN_OBJECT (ptr); - DEBUG (6, fprintf (gc_debug_file, "Unmarked pinned object %p (%s)\n", ptr, sgen_safe_name (ptr))); + SGEN_LOG (6, "Unmarked pinned object %p (%s)", ptr, sgen_safe_name (ptr)); } else { - DEBUG (6, fprintf (gc_debug_file, "Freeing unmarked pinned object %p (%s)\n", ptr, sgen_safe_name (ptr))); + SGEN_LOG (6, "Freeing unmarked pinned object %p (%s)", ptr, sgen_safe_name (ptr)); free_pinned_object (ptr, size); } } @@ -481,7 +470,7 @@ pin_pinned_object_callback (void *addr, size_t slot_size, SgenGrayQueue *queue) sgen_pin_stats_register_object ((char*) addr, sgen_safe_object_get_size ((MonoObject*) addr)); SGEN_PIN_OBJECT (addr); GRAY_OBJECT_ENQUEUE (queue, addr); - DEBUG (6, fprintf (gc_debug_file, "Marked pinned object %p (%s) from roots\n", addr, sgen_safe_name (addr))); + SGEN_LOG (6, "Marked pinned object %p (%s) from roots", addr, sgen_safe_name (addr)); } static void @@ -547,7 +536,7 @@ major_sweep (void) free_major_section (to_free); continue; } else { - DEBUG (6, fprintf (gc_debug_file, "Section %p has still pinned objects (%d)\n", section, section->pin_queue_num_entries)); + SGEN_LOG (6, "Section %p has still pinned objects (%d)", section, section->pin_queue_num_entries); build_section_fragments (section); } prev_section = section; @@ -699,4 +688,15 @@ sgen_copying_init (SgenMajorCollector *collector) collector->major_ops.scan_object = major_scan_object; } +#else /* DISABLE_SGEN_MAJOR_COPYING */ + +void +sgen_copying_init (SgenMajorCollector *collector) +{ + fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_copying.\n"); + exit (1); +} + +#endif /* DISABLE_SGEN_MAJOR_COPYING */ + #endif diff --git a/mono/metadata/sgen-major-scan-object.h b/mono/metadata/sgen-major-scan-object.h index 9266a6cae24..bea59c52a1b 100644 --- a/mono/metadata/sgen-major-scan-object.h +++ b/mono/metadata/sgen-major-scan-object.h @@ -1,26 +1,24 @@ /* + * sgen-major-scan-object.h: Object scanning in the major collectors. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + extern long long stat_scan_object_called_major; #ifdef FIXED_HEAP @@ -37,7 +35,7 @@ extern long long stat_scan_object_called_major; PREFETCH_DYNAMIC_HEAP (__old); \ major_copy_or_mark_object ((ptr), queue); \ __copy = *(ptr); \ - DEBUG (9, if (__old != __copy) sgen_debug_printf (9, "Overwrote field at %p with %p (was: %p)\n", (ptr), *(ptr), __old)); \ + SGEN_COND_LOG (9, __old != __copy, "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \ if (G_UNLIKELY (sgen_ptr_in_nursery (__copy) && !sgen_ptr_in_nursery ((ptr)))) \ sgen_add_to_global_remset ((ptr)); \ } \ diff --git a/mono/metadata/sgen-marksweep-fixed-par.c b/mono/metadata/sgen-marksweep-fixed-par.c index b023a6124dd..1d93023b514 100644 --- a/mono/metadata/sgen-marksweep-fixed-par.c +++ b/mono/metadata/sgen-marksweep-fixed-par.c @@ -1,4 +1,25 @@ +#include "config.h" + +#ifdef HAVE_SGEN_GC + +#ifndef DISABLE_SGEN_MARKSWEEP_FIXED_PAR + #define SGEN_PARALLEL_MARK #define FIXED_HEAP #include "sgen-marksweep.c" + +#else + +#include "metadata/sgen-gc.h" + +void +sgen_marksweep_fixed_par_init (SgenMajorCollector *collector) +{ + fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_fixed_par.\n"); + exit (1); +} + +#endif + +#endif diff --git a/mono/metadata/sgen-marksweep-fixed.c b/mono/metadata/sgen-marksweep-fixed.c index 875a18a4c29..732d29c511c 100644 --- a/mono/metadata/sgen-marksweep-fixed.c +++ b/mono/metadata/sgen-marksweep-fixed.c @@ -1,3 +1,24 @@ +#include "config.h" + +#ifdef HAVE_SGEN_GC + +#ifndef DISABLE_SGEN_MARKSWEEP_FIXED + #define FIXED_HEAP #include "sgen-marksweep.c" + +#else + +#include "metadata/sgen-gc.h" + +void +sgen_marksweep_fixed_init (SgenMajorCollector *collector) +{ + fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_fixed.\n"); + exit (1); +} + +#endif + +#endif diff --git a/mono/metadata/sgen-marksweep-par.c b/mono/metadata/sgen-marksweep-par.c index e728ee34dfa..5bc7805c870 100644 --- a/mono/metadata/sgen-marksweep-par.c +++ b/mono/metadata/sgen-marksweep-par.c @@ -1,3 +1,24 @@ +#include "config.h" + +#ifdef HAVE_SGEN_GC + +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_PAR + #define SGEN_PARALLEL_MARK #include "sgen-marksweep.c" + +#else + +#include "metadata/sgen-gc.h" + +void +sgen_marksweep_par_init (SgenMajorCollector *collector) +{ + fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_par.\n"); + exit (1); +} + +#endif /* DISABLE_SGEN_MAJOR_MARKSWEEP_PAR */ + +#endif diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c index d861f22f252..eeeefcc2152 100644 --- a/mono/metadata/sgen-marksweep.c +++ b/mono/metadata/sgen-marksweep.c @@ -1,29 +1,24 @@ /* - * sgen-marksweep.c: Simple generational GC. + * sgen-marksweep.c: The Mark & Sweep major collector. * * Author: * Mark Probst * * Copyright 2009-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -88,6 +83,7 @@ struct _MSBlockInfo { unsigned int has_references : 1; unsigned int has_pinned : 1; /* means cannot evacuate */ unsigned int is_to_space : 1; + unsigned int swept : 1; #ifdef FIXED_HEAP unsigned int used : 1; unsigned int zeroed : 1; @@ -113,6 +109,7 @@ static MSBlockInfo *block_infos; #endif #define MS_BLOCK_OBJ(b,i) ((b)->block + MS_BLOCK_SKIP + (b)->obj_size * (i)) +#define MS_BLOCK_OBJ_FOR_SIZE(b,i,obj_size) ((b)->block + MS_BLOCK_SKIP + (obj_size) * (i)) #define MS_BLOCK_DATA_FOR_OBJ(o) ((char*)((mword)(o) & ~(mword)(MS_BLOCK_SIZE - 1))) #ifdef FIXED_HEAP @@ -185,6 +182,7 @@ static gboolean *evacuate_block_obj_sizes; static float evacuation_threshold = 0.666; static gboolean concurrent_sweep = FALSE; +static gboolean lazy_sweep = TRUE; static gboolean have_swept; /* all allocated blocks in the system */ @@ -216,6 +214,7 @@ static MonoNativeTlsKey workers_free_block_lists_key; static long long stat_major_blocks_alloced = 0; static long long stat_major_blocks_freed = 0; +static long long stat_major_blocks_lazy_swept = 0; static long long stat_major_objects_evacuated = 0; static long long stat_time_wait_for_sweep = 0; @@ -224,6 +223,9 @@ static MonoNativeThreadId ms_sweep_thread; static MonoSemType ms_sweep_cmd_semaphore; static MonoSemType ms_sweep_done_semaphore; +static void +sweep_block (MSBlockInfo *block); + static void ms_signal_sweep_command (void) { @@ -273,7 +275,7 @@ static int ms_find_block_obj_size_index (int size) { int i; - DEBUG (9, g_assert (size <= SGEN_MAX_SMALL_OBJ_SIZE)); + SGEN_ASSERT (9, size <= SGEN_MAX_SMALL_OBJ_SIZE, "size %d is bigger than max small object size %d", size, SGEN_MAX_SMALL_OBJ_SIZE); for (i = 0; i < num_block_obj_sizes; ++i) if (block_obj_sizes [i] >= size) return i; @@ -458,7 +460,8 @@ check_block_free_list (MSBlockInfo *block, int size, gboolean pinned) /* blocks in the free lists must have at least one free slot */ - g_assert (block->free_list); + if (block->swept) + g_assert (block->free_list); #ifdef FIXED_HEAP /* the block must not be in the empty_blocks list */ @@ -518,8 +521,10 @@ consistency_check (void) g_assert (num_free == 0); /* check all mark words are zero */ - for (i = 0; i < MS_NUM_MARK_WORDS; ++i) - g_assert (block->mark_words [i] == 0); + if (block->swept) { + for (i = 0; i < MS_NUM_MARK_WORDS; ++i) + g_assert (block->mark_words [i] == 0); + } } END_FOREACH_BLOCK; /* check free blocks */ @@ -558,7 +563,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) info = sgen_alloc_internal (INTERNAL_MEM_MS_BLOCK_INFO); #endif - DEBUG (9, g_assert (count >= 2)); + SGEN_ASSERT (9, count >= 2, "block with %d objects, it must hold at least 2", count); info->obj_size = size; info->obj_size_index = size_index; @@ -566,6 +571,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) info->has_references = has_references; info->has_pinned = pinned; info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD); /*FIXME WHY??? */ + info->swept = 1; #ifndef FIXED_HEAP info->block = ms_get_empty_block (); @@ -626,10 +632,15 @@ unlink_slot_from_free_list_uncontested (MSBlockInfo **free_blocks, int size_inde void *obj; block = free_blocks [size_index]; - DEBUG (9, g_assert (block)); + SGEN_ASSERT (9, block, "no free block to unlink from free_blocks %p size_index %d", free_blocks, size_index); + + if (G_UNLIKELY (!block->swept)) { + stat_major_blocks_lazy_swept ++; + sweep_block (block); + } obj = block->free_list; - DEBUG (9, g_assert (obj)); + SGEN_ASSERT (9, obj, "block %p in free list had no available object to alloc from", block); block->free_list = *(void**)obj; if (!block->free_list) { @@ -669,8 +680,8 @@ alloc_obj_par (int size, gboolean pinned, gboolean has_references) MSBlockInfo *block; void *obj; - DEBUG (9, g_assert (!ms_sweep_in_progress)); - DEBUG (9, g_assert (current_collection_generation == GENERATION_OLD)); + SGEN_ASSERT (9, !ms_sweep_in_progress, "concurrent sweep in progress with concurrent allocation"); + SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); if (free_blocks_local [size_index]) { get_slot: @@ -728,10 +739,11 @@ alloc_obj (int size, gboolean pinned, gboolean has_references) void *obj; #ifdef SGEN_PARALLEL_MARK - DEBUG (9, g_assert (current_collection_generation != GENERATION_OLD)); + SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); + #endif - DEBUG (9, g_assert (!ms_sweep_in_progress)); + SGEN_ASSERT (9, !ms_sweep_in_progress, "concurrent sweep in progress with concurrent allocation"); if (!free_blocks [size_index]) { if (G_UNLIKELY (!ms_alloc_block (size_index, pinned, has_references))) @@ -767,14 +779,17 @@ free_object (char *obj, size_t size, gboolean pinned) { MSBlockInfo *block = MS_BLOCK_FOR_OBJ (obj); int word, bit; - DEBUG (9, g_assert ((pinned && block->pinned) || (!pinned && !block->pinned))); - DEBUG (9, g_assert (MS_OBJ_ALLOCED (obj, block))); + + if (!block->swept) + sweep_block (block); + SGEN_ASSERT (9, (pinned && block->pinned) || (!pinned && !block->pinned), "free-object pinning mixup object %p pinned %d block %p pinned %d", obj, pinned, block, block->pinned); + SGEN_ASSERT (9, MS_OBJ_ALLOCED (obj, block), "object %p is already free", obj); MS_CALC_MARK_BIT (word, bit, obj); - DEBUG (9, g_assert (!MS_MARK_BIT (block, word, bit))); + SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p has mark bit set"); if (!block->free_list) { MSBlockInfo **free_blocks = FREE_BLOCKS (pinned, block->has_references); int size_index = MS_BLOCK_OBJ_SIZE_INDEX (size); - DEBUG (9, g_assert (!block->next_free)); + SGEN_ASSERT (9, !block->next_free, "block %p doesn't have a free-list of object but belongs to a free-list of blocks"); block->next_free = free_blocks [size_index]; free_blocks [size_index] = block; } @@ -871,7 +886,7 @@ major_is_object_live (char *obj) /* now we know it's in a major block */ block = MS_BLOCK_FOR_OBJ (obj); - DEBUG (9, g_assert (!block->pinned)); + SGEN_ASSERT (9, !block->pinned, "block %p is pinned, BTW why is this bad?"); MS_CALC_MARK_BIT (word, bit, obj); return MS_MARK_BIT (block, word, bit) ? TRUE : FALSE; } @@ -903,6 +918,8 @@ major_iterate_objects (gboolean non_pinned, gboolean pinned, IterateObjectCallba continue; if (!block->pinned && !non_pinned) continue; + if (lazy_sweep) + sweep_block (block); for (i = 0; i < count; ++i) { void **obj = (void**) MS_BLOCK_OBJ (block, i); @@ -950,7 +967,7 @@ major_describe_pointer (char *ptr) if ((block->block > ptr) || ((block->block + MS_BLOCK_SIZE) <= ptr)) continue; - fprintf (gc_debug_file, "major-ptr (block %p sz %d pin %d ref %d) ", + SGEN_LOG (1, "major-ptr (block %p sz %d pin %d ref %d) ", block->block, block->obj_size, block->pinned, block->has_references); idx = MS_BLOCK_OBJ_INDEX (ptr, block); @@ -960,16 +977,16 @@ major_describe_pointer (char *ptr) if (obj == ptr) { if (live) - fprintf (gc_debug_file, "(object %s.%s)", vtable->klass->name_space, vtable->klass->name); + SGEN_LOG (1, "\t(object %s.%s)", vtable->klass->name_space, vtable->klass->name); else - fprintf (gc_debug_file, "(dead-object)"); + SGEN_LOG (1, "(dead-object)"); } else { if (live) - fprintf (gc_debug_file, "(interior-ptr offset %td of %p %s.%s)", + SGEN_LOG (1, "(interior-ptr offset %td of %p %s.%s)", ptr - obj, obj, vtable->klass->name_space, vtable->klass->name); else - fprintf (gc_debug_file, "(dead-interior-ptr to %td to %p)", + SGEN_LOG (1, "(dead-interior-ptr to %td to %p)", ptr - obj, obj); } @@ -1051,7 +1068,7 @@ major_dump_heap (FILE *heap_dump_file) #define MS_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \ int __word, __bit; \ MS_CALC_MARK_BIT (__word, __bit, (obj)); \ - DEBUG (9, g_assert (MS_OBJ_ALLOCED ((obj), (block)))); \ + SGEN_ASSERT (9, MS_OBJ_ALLOCED ((obj), (block)), "object %p not allocated", obj); \ if (!MS_MARK_BIT ((block), __word, __bit)) { \ MS_SET_MARK_BIT ((block), __word, __bit); \ if ((block)->has_references) \ @@ -1062,7 +1079,7 @@ major_dump_heap (FILE *heap_dump_file) #define MS_PAR_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \ int __word, __bit; \ gboolean __was_marked; \ - DEBUG (9, g_assert (MS_OBJ_ALLOCED ((obj), (block)))); \ + SGEN_ASSERT (9, MS_OBJ_ALLOCED ((obj), (block)), "object %p not allocated", obj); \ MS_CALC_MARK_BIT (__word, __bit, (obj)); \ MS_PAR_SET_MARK_BIT (__was_marked, (block), __word, __bit); \ if (!__was_marked) { \ @@ -1093,8 +1110,8 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue) HEAVY_STAT (++stat_copy_object_called_major); - DEBUG (9, g_assert (obj)); - DEBUG (9, g_assert (current_collection_generation == GENERATION_OLD)); + SGEN_ASSERT (9, obj, "null object from pointer %p", ptr); + SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); if (sgen_ptr_in_nursery (obj)) { int word, bit; @@ -1166,7 +1183,7 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue) if (!sgen_ptr_in_nursery (obj)) { block = MS_BLOCK_FOR_OBJ (obj); MS_CALC_MARK_BIT (word, bit, obj); - DEBUG (9, g_assert (!MS_MARK_BIT (block, word, bit))); + SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p already marked", obj); MS_PAR_SET_MARK_BIT (was_marked, block, word, bit); } } else { @@ -1256,8 +1273,8 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue) HEAVY_STAT (++stat_copy_object_called_major); - DEBUG (9, g_assert (obj)); - DEBUG (9, g_assert (current_collection_generation == GENERATION_OLD)); + SGEN_ASSERT (9, obj, "null object from pointer %p", ptr); + SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); if (sgen_ptr_in_nursery (obj)) { int word, bit; @@ -1308,7 +1325,7 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue) if (!sgen_ptr_in_nursery (obj)) { block = MS_BLOCK_FOR_OBJ (obj); MS_CALC_MARK_BIT (word, bit, obj); - DEBUG (9, g_assert (!MS_MARK_BIT (block, word, bit))); + SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p already marked", obj); MS_SET_MARK_BIT (block, word, bit); } } else { @@ -1397,7 +1414,7 @@ mark_pinned_objects_in_block (MSBlockInfo *block, SgenGrayQueue *queue) for (i = 0; i < block->pin_queue_num_entries; ++i) { int index = MS_BLOCK_OBJ_INDEX (block->pin_queue_start [i], block); - DEBUG (9, g_assert (index >= 0 && index < MS_BLOCK_FREE / block->obj_size)); + SGEN_ASSERT (9, index >= 0 && index < MS_BLOCK_FREE / block->obj_size, "invalid object %p index %d max-index %d", block->pin_queue_start [i], index, MS_BLOCK_FREE / block->obj_size); if (index == last_index) continue; MS_MARK_OBJECT_AND_ENQUEUE_CHECKED (MS_BLOCK_OBJ (block, index), block, queue); @@ -1405,6 +1422,97 @@ mark_pinned_objects_in_block (MSBlockInfo *block, SgenGrayQueue *queue) } } +static inline void +sweep_block_for_size (MSBlockInfo *block, int count, int obj_size) +{ + int obj_index; + + for (obj_index = 0; obj_index < count; ++obj_index) { + int word, bit; + void *obj = MS_BLOCK_OBJ_FOR_SIZE (block, obj_index, obj_size); + + MS_CALC_MARK_BIT (word, bit, obj); + if (MS_MARK_BIT (block, word, bit)) { + SGEN_ASSERT (9, MS_OBJ_ALLOCED (obj, block), "object %p not allocated", obj); + } else { + /* an unmarked object */ + if (MS_OBJ_ALLOCED (obj, block)) { + /* + * FIXME: Merge consecutive + * slots for lower reporting + * overhead. Maybe memset + * will also benefit? + */ + binary_protocol_empty (obj, obj_size); + MONO_GC_MAJOR_SWEPT ((mword)obj, obj_size); + memset (obj, 0, obj_size); + } + *(void**)obj = block->free_list; + block->free_list = obj; + } + } +} + +/* + * sweep_block: + * + * Traverse BLOCK, freeing and zeroing unused objects. + */ +static void +sweep_block (MSBlockInfo *block) +{ + int count; + + if (block->swept) + return; + + count = MS_BLOCK_FREE / block->obj_size; + + block->free_list = NULL; + + /* Use inline instances specialized to constant sizes, this allows the compiler to replace the memset calls with inline code */ + // FIXME: Add more sizes + switch (block->obj_size) { + case 16: + sweep_block_for_size (block, count, 16); + break; + default: + sweep_block_for_size (block, count, block->obj_size); + break; + } + + /* reset mark bits */ + memset (block->mark_words, 0, sizeof (mword) * MS_NUM_MARK_WORDS); + + /* + * FIXME: reverse free list so that it's in address + * order + */ + + block->swept = 1; +} + +static inline int +bitcount (mword d) +{ +#if SIZEOF_VOID_P == 8 + /* http://www.jjj.de/bitwizardry/bitwizardrypage.html */ + d -= (d>>1) & 0x5555555555555555; + d = ((d>>2) & 0x3333333333333333) + (d & 0x3333333333333333); + d = ((d>>4) + d) & 0x0f0f0f0f0f0f0f0f; + d *= 0x0101010101010101; + return d >> 56; +#else + /* http://aggregate.org/MAGIC/ */ + d -= ((d >> 1) & 0x55555555); + d = (((d >> 2) & 0x33333333) + (d & 0x33333333)); + d = (((d >> 4) + d) & 0x0f0f0f0f); + d += (d >> 8); + d += (d >> 16); + return (d & 0x0000003f); +#endif +} + static void ms_sweep (void) { @@ -1434,8 +1542,9 @@ ms_sweep (void) int count; gboolean have_live = FALSE; gboolean has_pinned; - int obj_index; + gboolean have_free = FALSE; int obj_size_index; + int nused = 0; obj_size_index = block->obj_size_index; @@ -1443,49 +1552,27 @@ ms_sweep (void) block->has_pinned = block->pinned; block->is_to_space = FALSE; + block->swept = 0; count = MS_BLOCK_FREE / block->obj_size; - block->free_list = NULL; - for (obj_index = 0; obj_index < count; ++obj_index) { - int word, bit; - void *obj = MS_BLOCK_OBJ (block, obj_index); - - MS_CALC_MARK_BIT (word, bit, obj); - if (MS_MARK_BIT (block, word, bit)) { - DEBUG (9, g_assert (MS_OBJ_ALLOCED (obj, block))); - have_live = TRUE; - if (!has_pinned) - ++slots_used [obj_size_index]; - } else { - /* an unmarked object */ - if (MS_OBJ_ALLOCED (obj, block)) { - /* - * FIXME: Merge consecutive - * slots for lower reporting - * overhead. Maybe memset - * will also benefit? - */ - binary_protocol_empty (obj, block->obj_size); - MONO_GC_MAJOR_SWEPT ((mword)obj, block->obj_size); - memset (obj, 0, block->obj_size); - } - *(void**)obj = block->free_list; - block->free_list = obj; - } + /* Count marked objects in the block */ + for (i = 0; i < MS_NUM_MARK_WORDS; ++i) { + nused += bitcount (block->mark_words [i]); } + if (nused) { + have_live = TRUE; + } + if (nused < count) + have_free = TRUE; - /* reset mark bits */ - memset (block->mark_words, 0, sizeof (mword) * MS_NUM_MARK_WORDS); - - /* - * FIXME: reverse free list so that it's in address - * order - */ + if (!lazy_sweep) + sweep_block (block); if (have_live) { if (!has_pinned) { ++num_blocks [obj_size_index]; + slots_used [obj_size_index] += nused; slots_available [obj_size_index] += count; } @@ -1495,7 +1582,7 @@ ms_sweep (void) * If there are free slots in the block, add * the block to the corresponding free list. */ - if (block->free_list) { + if (have_free) { MSBlockInfo **free_blocks = FREE_BLOCKS (block->pinned, block->has_references); int index = MS_BLOCK_OBJ_SIZE_INDEX (block->obj_size); block->next_free = free_blocks [index]; @@ -1521,7 +1608,6 @@ ms_sweep (void) --num_major_sections; } } - for (i = 0; i < num_block_obj_sizes; ++i) { float usage = (float)slots_used [i] / (float)slots_available [i]; if (num_blocks [i] > 5 && usage < evacuation_threshold) { @@ -1681,6 +1767,20 @@ major_start_major_collection (void) free_block_lists [0][i] = NULL; free_block_lists [MS_BLOCK_FLAG_REFS][i] = NULL; } + + // Sweep all unswept blocks + if (lazy_sweep) { + MSBlockInfo **iter; + + iter = &all_blocks; + while (*iter) { + MSBlockInfo *block = *iter; + + sweep_block (block); + + iter = &block->next; + } + } } static void @@ -1923,6 +2023,9 @@ major_scan_card_table (SgenGrayQueue *queue) continue; #endif + if (!block->swept) + sweep_block (block); + obj = (char*)MS_BLOCK_OBJ_FAST (block_start, block_obj_size, 0); end = block_start + MS_BLOCK_SIZE; base = sgen_card_table_align_pointer (obj); @@ -1960,6 +2063,9 @@ major_scan_card_table (SgenGrayQueue *queue) if (!*card_data) continue; + if (!block->swept) + sweep_block (block); + HEAVY_STAT (++marked_cards); sgen_card_table_prepare_card_for_scanning (card_data); @@ -2109,6 +2215,7 @@ sgen_marksweep_init mono_counters_register ("# major blocks allocated", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_alloced); mono_counters_register ("# major blocks freed", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_freed); + mono_counters_register ("# major blocks lazy swept", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_lazy_swept); mono_counters_register ("# major objects evacuated", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_objects_evacuated); mono_counters_register ("Wait for sweep time", MONO_COUNTER_GC | MONO_COUNTER_TIME_INTERVAL, &stat_time_wait_for_sweep); #ifdef SGEN_PARALLEL_MARK diff --git a/mono/metadata/sgen-memory-governor.c b/mono/metadata/sgen-memory-governor.c index 7fff99a6b73..445328c193e 100644 --- a/mono/metadata/sgen-memory-governor.c +++ b/mono/metadata/sgen-memory-governor.c @@ -1,33 +1,27 @@ /* - * sgen-cardtable.c: Card table implementation for sgen + * sgen-memory-governor.c: When to schedule collections based on + * memory usage. * * Author: * Rodrigo Kumpera (rkumpera@novell.com) * - * SGen is licensed under the terms of the MIT X11 license - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -145,11 +139,11 @@ sgen_memgov_try_calculate_minor_collection_allowance (gboolean overwrite) if (debug_print_allowance) { mword old_major = last_collection_old_num_major_sections * major_collector.section_size; - fprintf (gc_debug_file, "Before collection: %td bytes (%td major, %td LOS)\n", + SGEN_LOG (1, "Before collection: %td bytes (%td major, %td LOS)", old_major + last_collection_old_los_memory_usage, old_major, last_collection_old_los_memory_usage); - fprintf (gc_debug_file, "After collection: %td bytes (%td major, %td LOS)\n", + SGEN_LOG (1, "After collection: %td bytes (%td major, %td LOS)", new_heap_size, new_major, last_collection_los_memory_usage); - fprintf (gc_debug_file, "Allowance: %td bytes\n", minor_collection_allowance); + SGEN_LOG (1, "Allowance: %td bytes", minor_collection_allowance); } if (major_collector.have_computed_minor_collection_allowance) @@ -222,7 +216,7 @@ log_timming (GGTimingInfo *info) if (info->generation == GENERATION_OLD) mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MAJOR%s: (%s) pause %.2fms, %s major %dK/%dK los %dK/%dK", info->is_overflow ? "_OVERFLOW" : "", - info->reason, + info->reason ? info->reason : "", (int)info->total_time / 1000.0f, full_timing_buff, major_collector.section_size * num_major_sections / 1024, @@ -232,7 +226,7 @@ log_timming (GGTimingInfo *info) else mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_MINOR%s: (%s) pause %.2fms, %s promoted %dK major %dK los %dK", info->is_overflow ? "_OVERFLOW" : "", - info->reason, + info->reason ? info->reason : "", (int)info->total_time / 1000.0f, full_timing_buff, (num_major_sections - last_major_num_sections) * major_collector.section_size / 1024, @@ -245,7 +239,7 @@ sgen_memgov_collection_end (int generation, GGTimingInfo* info, int info_count) { int i; for (i = 0; i < info_count; ++i) { - if (info->generation != -1) + if (info[i].generation != -1) log_timming (&info [i]); } } diff --git a/mono/metadata/sgen-minor-copy-object.h b/mono/metadata/sgen-minor-copy-object.h index 0546201f76a..5b03713840e 100644 --- a/mono/metadata/sgen-minor-copy-object.h +++ b/mono/metadata/sgen-minor-copy-object.h @@ -1,37 +1,267 @@ /* + * sgen-minor-copy-object.h: Copy functions for nursery collections. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue); -#define collector_serial_alloc_for_promotion alloc_for_promotion -#define collector_parallel_alloc_for_promotion par_alloc_for_promotion - -#define GENERATE_COPY_FUNCTIONS 1 +#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion +#define COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION par_alloc_for_promotion +extern long long stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */ #include "sgen-copy-object.h" +/* + * This is how the copying happens from the nursery to the old generation. + * We assume that at this time all the pinned objects have been identified and + * marked as such. + * We run scan_object() for each pinned object so that each referenced + * objects if possible are copied. The new gray objects created can have + * scan_object() run on them right away, too. + * Then we run copy_object() for the precisely tracked roots. At this point + * all the roots are either gray or black. We run scan_object() on the gray + * objects until no more gray objects are created. + * At the end of the process we walk again the pinned list and we unmark + * the pinned flag. As we go we also create the list of free space for use + * in the next allocation runs. + * + * We need to remember objects from the old generation that point to the new one + * (or just addresses?). + * + * copy_object could be made into a macro once debugged (use inline for now). + */ + +#ifdef _MSC_VER +static __forceinline void +#else +static inline void __attribute__((always_inline)) +#endif +SERIAL_COPY_OBJECT (void **obj_slot, SgenGrayQueue *queue) +{ + char *forwarded; + char *obj = *obj_slot; + + SGEN_ASSERT (9, current_collection_generation == GENERATION_NURSERY, "calling minor-serial-copy from a %d generation collection", current_collection_generation); + + HEAVY_STAT (++stat_copy_object_called_nursery); + + if (!sgen_ptr_in_nursery (obj)) { + HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); + return; + } + + SGEN_LOG (9, "Precise copy of %p from %p", obj, obj_slot); + + /* + * Before we can copy the object we must make sure that we are + * allowed to, i.e. that the object not pinned, not already + * forwarded or belongs to the nursery To Space. + */ + + if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { + SGEN_ASSERT (9, (*(MonoVTable**)SGEN_LOAD_VTABLE (obj))->gc_descr, "forwarded object %p has no gc descriptor", forwarded); + SGEN_LOG (9, " (already forwarded to %p)", forwarded); + HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); + *obj_slot = forwarded; + return; + } + if (G_UNLIKELY (SGEN_OBJECT_IS_PINNED (obj))) { + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "pinned object %p has no gc descriptor", obj); + SGEN_LOG (9, " (pinned, no change)"); + HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); + return; + } + +#ifndef SGEN_SIMPLE_NURSERY + if (sgen_nursery_is_to_space (obj)) { + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "to space object %p has no gc descriptor", obj); + SGEN_LOG (9, " (tospace, no change)"); + HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); + return; + } +#endif + + HEAVY_STAT (++stat_objects_copied_nursery); + + *obj_slot = copy_object_no_checks (obj, queue); +} + +/* + * SERIAL_COPY_OBJECT_FROM_OBJ: + * + * Similar to SERIAL_COPY_OBJECT, but assumes that OBJ_SLOT is part of an object, so it handles global remsets as well. + */ +#ifdef _MSC_VER +static __forceinline void +#else +static inline void __attribute__((always_inline)) +#endif +SERIAL_COPY_OBJECT_FROM_OBJ (void **obj_slot, SgenGrayQueue *queue) +{ + char *forwarded; + char *obj = *obj_slot; + void *copy; + + SGEN_ASSERT (9, current_collection_generation == GENERATION_NURSERY, "calling minor-serial-copy-from-obj from a %d generation collection", current_collection_generation); + + HEAVY_STAT (++stat_copy_object_called_nursery); + + if (!sgen_ptr_in_nursery (obj)) { + HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); + return; + } + + SGEN_LOG (9, "Precise copy of %p from %p", obj, obj_slot); + + /* + * Before we can copy the object we must make sure that we are + * allowed to, i.e. that the object not pinned, not already + * forwarded or belongs to the nursery To Space. + */ + + if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { + SGEN_ASSERT (9, (*(MonoVTable**)SGEN_LOAD_VTABLE (obj))->gc_descr, "forwarded object %p has no gc descriptor", forwarded); + SGEN_LOG (9, " (already forwarded to %p)", forwarded); + HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); + *obj_slot = forwarded; +#ifndef SGEN_SIMPLE_NURSERY + if (G_UNLIKELY (sgen_ptr_in_nursery (forwarded) && !sgen_ptr_in_nursery (obj_slot))) + sgen_add_to_global_remset (obj_slot); +#endif + return; + } + if (G_UNLIKELY (SGEN_OBJECT_IS_PINNED (obj))) { + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "pinned object %p has no gc descriptor", obj); + SGEN_LOG (9, " (pinned, no change)"); + HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); + if (!sgen_ptr_in_nursery (obj_slot)) + sgen_add_to_global_remset (obj_slot); + return; + } + +#ifndef SGEN_SIMPLE_NURSERY + if (sgen_nursery_is_to_space (obj)) { + SGEN_ASSERT (9, ((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr, "to space object %p has no gc descriptor", obj); + SGEN_LOG (9, " (tospace, no change)"); + HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); + return; + } +#endif + + HEAVY_STAT (++stat_objects_copied_nursery); + + copy = copy_object_no_checks (obj, queue); + *obj_slot = copy; +#ifndef SGEN_SIMPLE_NURSERY + if (G_UNLIKELY (sgen_ptr_in_nursery (copy) && !sgen_ptr_in_nursery (obj_slot))) + sgen_add_to_global_remset (obj_slot); +#else + /* copy_object_no_checks () can return obj on OOM */ + if (G_UNLIKELY (obj == copy)) { + if (G_UNLIKELY (sgen_ptr_in_nursery (copy) && !sgen_ptr_in_nursery (obj_slot))) + sgen_add_to_global_remset (obj_slot); + } +#endif +} + +static void +PARALLEL_COPY_OBJECT (void **obj_slot, SgenGrayQueue *queue) +{ + char *obj = *obj_slot; + mword vtable_word, objsize; + MonoVTable *vt; + void *destination; + gboolean has_references; + + SGEN_ASSERT (9, current_collection_generation == GENERATION_NURSERY, "calling minor-par-copy from a %d generation collection", current_collection_generation); + + HEAVY_STAT (++stat_copy_object_called_nursery); + + if (!sgen_ptr_in_nursery (obj)) { + HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); + return; + } + + vtable_word = *(mword*)obj; + vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); + + /* + * Before we can copy the object we must make sure that we are + * allowed to, i.e. that the object not pinned, not already + * forwarded and not in the nursery To Space. + */ + + if (vtable_word & SGEN_FORWARDED_BIT) { + HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); + *obj_slot = vt; + return; + } + if (vtable_word & SGEN_PINNED_BIT) { + HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); + return; + } + + if (sgen_nursery_is_to_space (obj)) { + HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); + return; + } + + HEAVY_STAT (++stat_objects_copied_nursery); + + objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); + has_references = SGEN_VTABLE_HAS_REFERENCES (vt); + + destination = COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION (obj, objsize, has_references); + + if (G_UNLIKELY (!destination)) { + sgen_parallel_pin_or_update (obj_slot, obj, vt, queue); + return; + } + + *(MonoVTable**)destination = vt; + + if (SGEN_CAS_PTR ((void*)obj, (void*)((mword)destination | SGEN_FORWARDED_BIT), vt) == vt) { + par_copy_object_no_checks (destination, vt, obj, objsize, has_references ? queue : NULL); + obj = destination; + *obj_slot = obj; + } else { + /* FIXME: unify with code in major_copy_or_mark_object() */ + + /* FIXME: Give destination back to the allocator. */ + /*The major collector only needs the first word zeroed and nursery requires all bits to be. */ + if (!sgen_ptr_in_nursery (destination)) + *(void**)destination = NULL; + else + memset (destination, 0, objsize); + + vtable_word = *(mword*)obj; + g_assert (vtable_word & SGEN_FORWARDED_BIT); + + obj = (void*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); + + *obj_slot = obj; + + HEAVY_STAT (++stat_slots_allocated_in_vain); + } +} + #define FILL_MINOR_COLLECTOR_COPY_OBJECT(collector) do { \ - (collector)->serial_ops.copy_or_mark_object = serial_copy_object; \ - (collector)->parallel_ops.copy_or_mark_object = parallel_copy_object; \ + (collector)->serial_ops.copy_or_mark_object = SERIAL_COPY_OBJECT; \ + (collector)->parallel_ops.copy_or_mark_object = PARALLEL_COPY_OBJECT; \ } while (0) diff --git a/mono/metadata/sgen-minor-scan-object.h b/mono/metadata/sgen-minor-scan-object.h index 89841202a0e..47c9be9fa31 100644 --- a/mono/metadata/sgen-minor-scan-object.h +++ b/mono/metadata/sgen-minor-scan-object.h @@ -1,39 +1,37 @@ /* + * sgen-minor-scan-object.h: Object scanning in the nursery collectors. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + extern long long stat_scan_object_called_nursery; #if defined(SGEN_SIMPLE_NURSERY) -#define serial_scan_object simple_nursery_serial_scan_object -#define serial_scan_vtype simple_nursery_serial_scan_vtype -#define parallel_scan_object simple_nursery_parallel_scan_object -#define parallel_scan_vtype simple_nursery_parallel_scan_vtype +#define SERIAL_SCAN_OBJECT simple_nursery_serial_scan_object +#define SERIAL_SCAN_VTYPE simple_nursery_serial_scan_vtype +#define PARALLEL_SCAN_OBJECT simple_nursery_parallel_scan_object +#define PARALLEL_SCAN_VTYPE simple_nursery_parallel_scan_vtype #elif defined (SGEN_SPLIT_NURSERY) -#define serial_scan_object split_nursery_serial_scan_object -#define serial_scan_vtype split_nursery_serial_scan_vtype -#define parallel_scan_object split_nursery_parallel_scan_object -#define parallel_scan_vtype split_nursery_parallel_scan_vtype +#define SERIAL_SCAN_OBJECT split_nursery_serial_scan_object +#define SERIAL_SCAN_VTYPE split_nursery_serial_scan_vtype +#define PARALLEL_SCAN_OBJECT split_nursery_parallel_scan_object +#define PARALLEL_SCAN_VTYPE split_nursery_parallel_scan_vtype #else #error "Please define GC_CONF_NAME" @@ -44,9 +42,9 @@ extern long long stat_scan_object_called_nursery; void *__old = *(ptr); \ void *__copy; \ if (__old) { \ - parallel_copy_object ((ptr), queue); \ + PARALLEL_COPY_OBJECT ((ptr), queue); \ __copy = *(ptr); \ - DEBUG (9, if (__old != __copy) fprintf (gc_debug_file, "Overwrote field at %p with %p (was: %p)\n", (ptr), *(ptr), __old)); \ + SGEN_COND_LOG (9, __old != __copy, "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \ if (G_UNLIKELY (sgen_ptr_in_nursery (__copy) && !sgen_ptr_in_nursery ((ptr)))) \ sgen_add_to_global_remset ((ptr)); \ } \ @@ -58,7 +56,7 @@ extern long long stat_scan_object_called_nursery; * them to the gray_objects area. */ static void -parallel_scan_object (char *start, SgenGrayQueue *queue) +PARALLEL_SCAN_OBJECT (char *start, SgenGrayQueue *queue) { #include "sgen-scan-object.h" @@ -73,7 +71,7 @@ parallel_scan_object (char *start, SgenGrayQueue *queue) * Returns a pointer to the end of the object. */ static void -parallel_scan_vtype (char *start, mword desc, SgenGrayQueue *queue) +PARALLEL_SCAN_VTYPE (char *start, mword desc, SgenGrayQueue *queue) { /* The descriptors include info about the MonoObject header as well */ start -= sizeof (MonoObject); @@ -83,20 +81,17 @@ parallel_scan_vtype (char *start, mword desc, SgenGrayQueue *queue) } #undef HANDLE_PTR +/* Global remsets are handled in SERIAL_COPY_OBJECT_FROM_OBJ */ #define HANDLE_PTR(ptr,obj) do { \ void *__old = *(ptr); \ - void *__copy; \ if (__old) { \ - serial_copy_object ((ptr), queue); \ - __copy = *(ptr); \ - DEBUG (9, if (__old != __copy) fprintf (gc_debug_file, "Overwrote field at %p with %p (was: %p)\n", (ptr), *(ptr), __old)); \ - if (G_UNLIKELY (sgen_ptr_in_nursery (__copy) && !sgen_ptr_in_nursery ((ptr)))) \ - sgen_add_to_global_remset ((ptr)); \ + SERIAL_COPY_OBJECT_FROM_OBJ ((ptr), queue); \ + SGEN_COND_LOG (9, __old != *(ptr), "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \ } \ } while (0) static void -serial_scan_object (char *start, SgenGrayQueue *queue) +SERIAL_SCAN_OBJECT (char *start, SgenGrayQueue *queue) { #include "sgen-scan-object.h" @@ -104,7 +99,7 @@ serial_scan_object (char *start, SgenGrayQueue *queue) } static void -serial_scan_vtype (char *start, mword desc, SgenGrayQueue *queue) +SERIAL_SCAN_VTYPE (char *start, mword desc, SgenGrayQueue *queue) { /* The descriptors include info about the MonoObject header as well */ start -= sizeof (MonoObject); @@ -114,8 +109,8 @@ serial_scan_vtype (char *start, mword desc, SgenGrayQueue *queue) } #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(collector) do { \ - (collector)->parallel_ops.scan_object = parallel_scan_object; \ - (collector)->parallel_ops.scan_vtype = parallel_scan_vtype; \ - (collector)->serial_ops.scan_object = serial_scan_object; \ - (collector)->serial_ops.scan_vtype = serial_scan_vtype; \ + (collector)->parallel_ops.scan_object = PARALLEL_SCAN_OBJECT; \ + (collector)->parallel_ops.scan_vtype = PARALLEL_SCAN_VTYPE; \ + (collector)->serial_ops.scan_object = SERIAL_SCAN_OBJECT; \ + (collector)->serial_ops.scan_vtype = SERIAL_SCAN_VTYPE; \ } while (0) diff --git a/mono/metadata/sgen-nursery-allocator.c b/mono/metadata/sgen-nursery-allocator.c index 73901bcbd9e..03e41566f35 100644 --- a/mono/metadata/sgen-nursery-allocator.c +++ b/mono/metadata/sgen-nursery-allocator.c @@ -1,31 +1,24 @@ /* * sgen-nursery-allocator.c: Nursery allocation code. * - * * Copyright 2009-2010 Novell, Inc. * 2011 Rodrigo Kumpera * * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Copyright (C) 2012 Xamarin Inc * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -643,7 +636,7 @@ sgen_clear_allocator_fragments (SgenFragmentAllocator *allocator) SgenFragment *frag; for (frag = unmask (allocator->alloc_head); frag; frag = unmask (frag->next)) { - DEBUG (4, fprintf (gc_debug_file, "Clear nursery frag %p-%p\n", frag->fragment_next, frag->fragment_end)); + SGEN_LOG (4, "Clear nursery frag %p-%p", frag->fragment_next, frag->fragment_end); sgen_clear_range (frag->fragment_next, frag->fragment_end); #ifdef NALLOC_DEBUG add_alloc_record (frag->fragment_next, frag->fragment_end - frag->fragment_next, CLEAR_NURSERY_FRAGS); @@ -710,7 +703,7 @@ static mword fragment_total = 0; static void add_nursery_frag (SgenFragmentAllocator *allocator, size_t frag_size, char* frag_start, char* frag_end) { - DEBUG (4, fprintf (gc_debug_file, "Found empty fragment: %p-%p, size: %zd\n", frag_start, frag_end, frag_size)); + SGEN_LOG (4, "Found empty fragment: %p-%p, size: %zd", frag_start, frag_end, frag_size); binary_protocol_empty (frag_start, frag_size); MONO_GC_NURSERY_SWEPT ((mword)frag_start, frag_end - frag_start); /* Not worth dealing with smaller fragments: need to tune */ @@ -828,9 +821,9 @@ sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start, int n sgen_minor_collector.build_fragments_finish (&mutator_allocator); if (!unmask (mutator_allocator.alloc_head)) { - DEBUG (1, fprintf (gc_debug_file, "Nursery fully pinned (%d)\n", num_entries)); + SGEN_LOG (1, "Nursery fully pinned (%d)", num_entries); for (i = 0; i < num_entries; ++i) { - DEBUG (3, fprintf (gc_debug_file, "Bastard pinning obj %p (%s), size: %d\n", start [i], sgen_safe_name (start [i]), sgen_safe_object_get_size (start [i]))); + SGEN_LOG (3, "Bastard pinning obj %p (%s), size: %d", start [i], sgen_safe_name (start [i]), sgen_safe_object_get_size (start [i])); } } return fragment_total; @@ -866,7 +859,7 @@ sgen_can_alloc_size (size_t size) void* sgen_nursery_alloc (size_t size) { - DEBUG (4, fprintf (gc_debug_file, "Searching nursery for size: %zd\n", size)); + SGEN_LOG (4, "Searching nursery for size: %zd", size); size = SGEN_ALIGN_UP (size); HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_requests)); @@ -877,7 +870,7 @@ sgen_nursery_alloc (size_t size) void* sgen_nursery_alloc_range (size_t desired_size, size_t minimum_size, size_t *out_alloc_size) { - DEBUG (4, fprintf (gc_debug_file, "Searching for byte range desired size: %zd minimum size %zd\n", desired_size, minimum_size)); + SGEN_LOG (4, "Searching for byte range desired size: %zd minimum size %zd", desired_size, minimum_size); HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_range_requests)); diff --git a/mono/metadata/sgen-os-mach.c b/mono/metadata/sgen-os-mach.c index 868f798261c..14290d373d6 100644 --- a/mono/metadata/sgen-os-mach.c +++ b/mono/metadata/sgen-os-mach.c @@ -1,5 +1,5 @@ /* - * sgen-os-mach.c: Simple generational GC. + * sgen-os-mach.c: Mach-OS support. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -7,25 +7,20 @@ * Geoff Norton (gnorton@novell.com) * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -76,7 +71,7 @@ sgen_suspend_thread (SgenThreadInfo *info) ctx.uc_mcontext = mctx; info->stopped_domain = mono_mach_arch_get_tls_value_from_thread ( - mono_thread_info_get_tid (info), mono_domain_get_tls_offset ()); + mono_thread_info_get_tid (info), mono_domain_get_tls_key ()); info->stopped_ip = (gpointer) mono_mach_arch_get_ip (state); info->stack_start = NULL; stack_start = (char*) mono_mach_arch_get_sp (state) - REDZONE_SIZE; @@ -97,7 +92,7 @@ sgen_suspend_thread (SgenThreadInfo *info) if (mono_gc_get_gc_callbacks ()->thread_suspend_func) mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, &ctx, NULL); - DEBUG (1, fprintf (gc_debug_file, "thread %p stopped at %p stack_start=%p\n", (void*)info->info.native_handle, info->stopped_ip, info->stack_start)); + SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)info->info.native_handle, info->stopped_ip, info->stack_start); binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->stopped_ip); diff --git a/mono/metadata/sgen-os-posix.c b/mono/metadata/sgen-os-posix.c index 1b1f2a56419..b4f84d3899a 100644 --- a/mono/metadata/sgen-os-posix.c +++ b/mono/metadata/sgen-os-posix.c @@ -1,5 +1,5 @@ /* - * sgen-os-posix.c: Simple generational GC. + * sgen-os-posix.c: Posix support. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -7,25 +7,20 @@ * Geoff Norton (gnorton@novell.com) * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -101,7 +96,7 @@ suspend_thread (SgenThreadInfo *info, void *context) if (mono_gc_get_gc_callbacks ()->thread_suspend_func) mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, context, NULL); - DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for suspend from %p %p\n", info, (gpointer)mono_native_thread_id_get ())); + SGEN_LOG (4, "Posting suspend_ack_semaphore for suspend from %p %p", info, (gpointer)mono_native_thread_id_get ()); /* Block the restart signal. @@ -123,7 +118,7 @@ suspend_thread (SgenThreadInfo *info, void *context) /* Unblock the restart signal. */ pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL); - DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ())); + SGEN_LOG (4, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ()); /* notify the waiting thread */ MONO_SEM_POST (suspend_ack_semaphore_ptr); } @@ -170,7 +165,7 @@ restart_handler (int sig) */ if (info) { info->signal = restart_signal_num; - DEBUG (4, fprintf (gc_debug_file, "Restart handler in %p %p\n", info, (gpointer)mono_native_thread_id_get ())); + SGEN_LOG (4, "Restart handler in %p %p", info, (gpointer)mono_native_thread_id_get ()); } errno = old_errno; } diff --git a/mono/metadata/sgen-pinned-allocator.c b/mono/metadata/sgen-pinned-allocator.c index 31d3cd678df..275e750cb30 100644 --- a/mono/metadata/sgen-pinned-allocator.c +++ b/mono/metadata/sgen-pinned-allocator.c @@ -1,5 +1,6 @@ /* - * sgen-pinned-allocator.c: Simple generational GC. + * sgen-pinned-allocator.c: Allocator for small pinned objects. + * Only used in the copying major collector. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -11,38 +12,22 @@ * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2004 by Hewlett-Packard Company. All rights reserved. + * Copyright 2001-2003 Ximian, Inc + * Copyright 2003-2010 Novell, Inc. + * Copyright (C) 2012 Xamarin Inc * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * Copyright 2001-2003 Ximian, Inc - * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -241,7 +226,7 @@ alloc_pinned_chunk (SgenPinnedAllocator *alc) chunk->page_sizes [0] = PINNED_FIRST_SLOT_SIZE; build_freelist (alc, chunk, slot_for_size (PINNED_FIRST_SLOT_SIZE), PINNED_FIRST_SLOT_SIZE, chunk->start_data, ((char*)chunk + FREELIST_PAGESIZE)); - sgen_debug_printf (4, "Allocated pinned chunk %p, size: %d\n", chunk, size); + SGEN_LOG (4, "Allocated pinned chunk %p, size: %d", chunk, size); chunk->block.next = alc->chunk_list; alc->chunk_list = chunk; @@ -408,14 +393,14 @@ sgen_pinned_scan_objects (SgenPinnedAllocator *alc, IterateObjectCallbackFunc ca void *end_chunk; for (chunk = alc->chunk_list; chunk; chunk = chunk->block.next) { end_chunk = (char*)chunk + chunk->num_pages * FREELIST_PAGESIZE; - sgen_debug_printf (6, "Scanning pinned chunk %p (range: %p-%p)\n", chunk, chunk->start_data, end_chunk); + SGEN_LOG (6, "Scanning pinned chunk %p (range: %p-%p)", chunk, chunk->start_data, end_chunk); for (i = 0; i < chunk->num_pages; ++i) { obj_size = chunk->page_sizes [i]; if (!obj_size) continue; p = i? (char*)chunk + i * FREELIST_PAGESIZE: chunk->start_data; endp = i? p + FREELIST_PAGESIZE: (char*)chunk + FREELIST_PAGESIZE; - sgen_debug_printf (6, "Page %d (size: %d, range: %p-%p)\n", i, obj_size, p, endp); + SGEN_LOG (6, "Page %d (size: %d, range: %p-%p)", i, obj_size, p, endp); while (p + obj_size <= endp) { ptr = (void**)p; /* if the first word (the vtable) is outside the chunk we have an object */ @@ -485,7 +470,7 @@ sgen_pinned_scan_pinned_objects (SgenPinnedAllocator *alc, IterateObjectCallback SgenPinnedChunk *chunk; /* look for pinned addresses for pinned-alloc objects */ - sgen_debug_printf (6, "Pinning from pinned-alloc objects\n"); + SGEN_LOG (6, "Pinning from pinned-alloc objects"); for (chunk = alc->chunk_list; chunk; chunk = chunk->block.next) { int num_pinned; void **pinned = sgen_find_optimized_pin_queue_area (chunk->start_data, diff --git a/mono/metadata/sgen-pinning.c b/mono/metadata/sgen-pinning.c index 0484500798a..3b1556bef52 100644 --- a/mono/metadata/sgen-pinning.c +++ b/mono/metadata/sgen-pinning.c @@ -1,25 +1,22 @@ /* + * sgen-pinning.c: The pin queue. + * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -58,7 +55,7 @@ realloc_pin_queue (void) sgen_free_internal_dynamic (pin_queue, sizeof (void*) * pin_queue_size, INTERNAL_MEM_PIN_QUEUE); pin_queue = new_pin; pin_queue_size = new_size; - DEBUG (4, fprintf (gc_debug_file, "Reallocated pin queue to size: %d\n", new_size)); + SGEN_LOG (4, "Reallocated pin queue to size: %d", new_size); } void @@ -107,9 +104,9 @@ sgen_find_optimized_pin_queue_area (void *start, void *end, int *num) void sgen_find_section_pin_queue_start_end (GCMemSection *section) { - DEBUG (6, fprintf (gc_debug_file, "Pinning from section %p (%p-%p)\n", section, section->data, section->end_data)); + SGEN_LOG (6, "Pinning from section %p (%p-%p)", section, section->data, section->end_data); section->pin_queue_start = sgen_find_optimized_pin_queue_area (section->data, section->end_data, §ion->pin_queue_num_entries); - DEBUG (6, fprintf (gc_debug_file, "Found %d pinning addresses in section %p\n", section->pin_queue_num_entries, section)); + SGEN_LOG (6, "Found %d pinning addresses in section %p", section->pin_queue_num_entries, section); } /*This will setup the given section for the while pin queue. */ @@ -144,21 +141,6 @@ sgen_pin_queue_clear_discarded_entries (GCMemSection *section, int max_pin_slot) } } -static G_GNUC_UNUSED void -print_nursery_gaps (void* start_nursery, void *end_nursery) -{ - int i; - gpointer first = start_nursery; - gpointer next; - for (i = 0; i < next_pin_slot; ++i) { - next = pin_queue [i]; - fprintf (gc_debug_file, "Nursery range: %p-%p, size: %td\n", first, next, (char*)next-(char*)first); - first = next; - } - next = end_nursery; - fprintf (gc_debug_file, "Nursery range: %p-%p, size: %td\n", first, next, (char*)next-(char*)first); -} - /* reduce the info in the pin queue, removing duplicate pointers and sorting them */ void sgen_optimize_pin_queue (int start_slot) @@ -166,7 +148,7 @@ sgen_optimize_pin_queue (int start_slot) void **start, **cur, **end; /* sort and uniq pin_queue: we just sort and we let the rest discard multiple values */ /* it may be better to keep ranges of pinned memory instead of individually pinning objects */ - DEBUG (5, fprintf (gc_debug_file, "Sorting pin queue, size: %d\n", next_pin_slot)); + SGEN_LOG (5, "Sorting pin queue, size: %d", next_pin_slot); if ((next_pin_slot - start_slot) > 1) sgen_sort_addresses (pin_queue + start_slot, next_pin_slot - start_slot); start = cur = pin_queue + start_slot; @@ -178,8 +160,7 @@ sgen_optimize_pin_queue (int start_slot) start++; }; next_pin_slot = start - pin_queue; - DEBUG (5, fprintf (gc_debug_file, "Pin queue reduced to size: %d\n", next_pin_slot)); - //DEBUG (6, print_nursery_gaps (start_nursery, end_nursery)); + SGEN_LOG (5, "Pin queue reduced to size: %d", next_pin_slot); } int @@ -194,7 +175,7 @@ sgen_dump_pin_queue (void) int i; for (i = 0; i < last_num_pinned; ++i) { - DEBUG (3, fprintf (gc_debug_file, "Bastard pinning obj %p (%s), size: %d\n", pin_queue [i], sgen_safe_name (pin_queue [i]), sgen_safe_object_get_size (pin_queue [i]))); + SGEN_LOG (3, "Bastard pinning obj %p (%s), size: %d", pin_queue [i], sgen_safe_name (pin_queue [i]), sgen_safe_object_get_size (pin_queue [i])); } } diff --git a/mono/metadata/sgen-simple-nursery.c b/mono/metadata/sgen-simple-nursery.c index 3c4ec7cd8fc..1dc06202e5a 100644 --- a/mono/metadata/sgen-simple-nursery.c +++ b/mono/metadata/sgen-simple-nursery.c @@ -1,31 +1,23 @@ /* * sgen-simple-nursery.c: Simple always promote nursery. * - * - * SGen is licensed under the terms of the MIT X11 license - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -85,6 +77,10 @@ init_nursery (SgenFragmentAllocator *allocator, char *start, char *end) #define SGEN_SIMPLE_NURSERY +#define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object +#define PARALLEL_COPY_OBJECT simple_nursery_parallel_copy_object +#define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj + #include "sgen-minor-copy-object.h" #include "sgen-minor-scan-object.h" diff --git a/mono/metadata/sgen-split-nursery.c b/mono/metadata/sgen-split-nursery.c index 60e4621330d..2d812767d3f 100644 --- a/mono/metadata/sgen-split-nursery.c +++ b/mono/metadata/sgen-split-nursery.c @@ -4,30 +4,23 @@ * Author: * Rodrigo Kumpera Kumpera * - * SGen is licensed under the terms of the MIT X11 license - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011-2012 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -523,10 +516,13 @@ print_gc_param_usage (void) #define SGEN_SPLIT_NURSERY +#define SERIAL_COPY_OBJECT split_nursery_serial_copy_object +#define PARALLEL_COPY_OBJECT split_nursery_parallel_copy_object +#define SERIAL_COPY_OBJECT_FROM_OBJ split_nursery_serial_copy_object_from_obj + #include "sgen-minor-copy-object.h" #include "sgen-minor-scan-object.h" - void sgen_split_nursery_init (SgenMinorCollector *collector) { diff --git a/mono/metadata/sgen-ssb.c b/mono/metadata/sgen-ssb.c index 0128fe5db15..4421a0dd577 100644 --- a/mono/metadata/sgen-ssb.c +++ b/mono/metadata/sgen-ssb.c @@ -1,33 +1,26 @@ /* - * sgen-cardtable.c: Card table implementation for sgen + * sgen-ssb.c: Remembered sets - sequential store buffer * * Author: * Rodrigo Kumpera (rkumpera@novell.com) * - * SGen is licensed under the terms of the MIT X11 license - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * Copyright 2011 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 - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -38,6 +31,8 @@ #include "metadata/sgen-protocol.h" #include "utils/mono-counters.h" +#ifndef DISABLE_SGEN_REMSET + /*A two slots cache for recently inserted remsets */ static gpointer global_remset_cache [2]; @@ -120,7 +115,7 @@ sgen_alloc_remset (int size, gpointer id, gboolean global) res->store_next = res->data; res->end_set = res->data + size; res->next = NULL; - DEBUG (4, fprintf (gc_debug_file, "Allocated%s remset size %d at %p for %p\n", global ? " global" : "", size, res->data, id)); + SGEN_LOG (4, "Allocated%s remset size %d at %p for %p", global ? " global" : "", size, res->data, id); return res; } @@ -185,7 +180,7 @@ sgen_ssb_wbarrier_arrayref_copy (gpointer dest_ptr, gpointer src_ptr, int count) mono_gc_memmove (dest_ptr, src_ptr, count * sizeof (gpointer)); rs = REMEMBERED_SET; - DEBUG (8, fprintf (gc_debug_file, "Adding remset at %p, %d\n", dest_ptr, count)); + SGEN_LOG (8, "Adding remset at %p, %d", dest_ptr, count); if (rs->store_next + 1 < rs->end_set) { *(rs->store_next++) = (mword)dest_ptr | REMSET_RANGE; *(rs->store_next++) = count; @@ -249,7 +244,7 @@ sgen_ssb_wbarrier_object_copy (MonoObject* obj, MonoObject *src) size = mono_object_class (obj)->instance_size; rs = REMEMBERED_SET; - DEBUG (6, fprintf (gc_debug_file, "Adding object remset for %p\n", obj)); + SGEN_LOG (6, "Adding object remset for %p", obj); LOCK_GC; /* do not copy the sync state */ @@ -417,7 +412,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global gpointer old = *ptr; sgen_get_current_object_ops ()->copy_or_mark_object (ptr, queue); - DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p\n", ptr, *ptr)); + SGEN_LOG (9, "Overwrote remset at %p with %p", ptr, *ptr); if (old) binary_protocol_ptr_update (ptr, old, *ptr, (gpointer)SGEN_LOAD_VTABLE (*ptr), sgen_safe_object_get_size (*ptr)); if (!global && *ptr >= start_nursery && *ptr < end_nursery) { @@ -425,11 +420,11 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global * If the object is pinned, each reference to it from nonpinned objects * becomes part of the global remset, which can grow very large. */ - DEBUG (9, fprintf (gc_debug_file, "Add to global remset because of pinning %p (%p %s)\n", ptr, *ptr, sgen_safe_name (*ptr))); + SGEN_LOG (9, "Add to global remset because of pinning %p (%p %s)", ptr, *ptr, sgen_safe_name (*ptr)); sgen_add_to_global_remset (ptr); } } else { - DEBUG (9, fprintf (gc_debug_file, "Skipping remset at %p holding %p\n", ptr, *ptr)); + SGEN_LOG (9, "Skipping remset at %p holding %p", ptr, *ptr); } return p + 1; case REMSET_RANGE: { @@ -441,7 +436,7 @@ handle_remset (mword *p, void *start_nursery, void *end_nursery, gboolean global count = p [1]; while (count-- > 0) { copy_func (ptr, queue); - DEBUG (9, fprintf (gc_debug_file, "Overwrote remset at %p with %p (count: %d)\n", ptr, *ptr, (int)count)); + SGEN_LOG (9, "Overwrote remset at %p with %p (count: %d)", ptr, *ptr, (int)count); if (!global && *ptr >= start_nursery && *ptr < end_nursery) sgen_add_to_global_remset (ptr); ++ptr; @@ -483,7 +478,7 @@ sgen_ssb_begin_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQue /* the global one */ for (remset = global_remset; remset; remset = remset->next) { - DEBUG (4, fprintf (gc_debug_file, "Scanning global remset range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning global remset range: %p-%p, size: %td", remset->data, remset->store_next, remset->store_next - remset->data); store_pos = remset->data; for (p = remset->data; p < remset->store_next; p = next_p) { void **ptr = (void**)p [0]; @@ -549,14 +544,14 @@ sgen_ssb_finish_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQu RememberedSet *next; int j; for (remset = info->remset; remset; remset = next) { - DEBUG (4, fprintf (gc_debug_file, "Scanning remset for thread %p, range: %p-%p, size: %td\n", info, remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning remset for thread %p, range: %p-%p, size: %td", info, remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) p = handle_remset (p, start_nursery, end_nursery, FALSE, queue); remset->store_next = remset->data; next = remset->next; remset->next = NULL; if (remset != info->remset) { - DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data)); + SGEN_LOG (4, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); } } @@ -569,11 +564,11 @@ sgen_ssb_finish_scan_remsets (void *start_nursery, void *end_nursery, SgenGrayQu while (freed_thread_remsets) { RememberedSet *next; remset = freed_thread_remsets; - DEBUG (4, fprintf (gc_debug_file, "Scanning remset for freed thread, range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning remset for freed thread, range: %p-%p, size: %td", remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) p = handle_remset (p, start_nursery, end_nursery, FALSE, queue); next = remset->next; - DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data)); + SGEN_LOG (4, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); freed_thread_remsets = next; } @@ -663,7 +658,7 @@ sgen_ssb_prepare_for_major_collection (void) next = remset->next; remset->next = NULL; if (remset != global_remset) { - DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data)); + SGEN_LOG (4, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); } } @@ -680,7 +675,7 @@ sgen_ssb_prepare_for_major_collection (void) next = remset->next; remset->next = NULL; if (remset != info->remset) { - DEBUG (3, fprintf (gc_debug_file, "Freed remset at %p\n", remset->data)); + SGEN_LOG (3, "Freed remset at %p", remset->data); sgen_free_internal_dynamic (remset, remset_byte_size (remset), INTERNAL_MEM_REMSET); } } @@ -690,7 +685,7 @@ sgen_ssb_prepare_for_major_collection (void) /* the freed thread ones */ while (freed_thread_remsets) { next = freed_thread_remsets->next; - DEBUG (4, fprintf (gc_debug_file, "Freed remset at %p\n", freed_thread_remsets->data)); + SGEN_LOG (4, "Freed remset at %p", freed_thread_remsets->data); sgen_free_internal_dynamic (freed_thread_remsets, remset_byte_size (freed_thread_remsets), INTERNAL_MEM_REMSET); freed_thread_remsets = next; } @@ -751,7 +746,7 @@ sgen_ssb_record_pointer (gpointer ptr) if (G_UNLIKELY (do_pin_stats)) sgen_pin_stats_register_global_remset (obj); - DEBUG (8, fprintf (gc_debug_file, "Adding global remset for %p\n", ptr)); + SGEN_LOG (8, "Adding global remset for %p", ptr); binary_protocol_global_remset (ptr, *(gpointer*)ptr, (gpointer)SGEN_LOAD_VTABLE (obj)); HEAVY_STAT (++stat_global_remsets_added); @@ -775,7 +770,7 @@ sgen_ssb_record_pointer (gpointer ptr) for (rs = global_remset; rs; rs = rs->next) { global_rs_size += rs->store_next - rs->data; } - DEBUG (4, fprintf (gc_debug_file, "Global remset now has size %d\n", global_rs_size)); + SGEN_LOG (4, "Global remset now has size %d", global_rs_size); } done: @@ -848,7 +843,7 @@ sgen_ssb_find_address (char *addr) /* the global one */ for (remset = global_remset; remset; remset = remset->next) { - DEBUG (4, fprintf (gc_debug_file, "Scanning global remset range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning global remset range: %p-%p, size: %td", remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) { p = find_in_remset_loc (p, addr, &found); if (found) @@ -868,7 +863,7 @@ sgen_ssb_find_address (char *addr) FOREACH_THREAD (info) { int j; for (remset = info->remset; remset; remset = remset->next) { - DEBUG (4, fprintf (gc_debug_file, "Scanning remset for thread %p, range: %p-%p, size: %td\n", info, remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning remset for thread %p, range: %p-%p, size: %td", info, remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) { p = find_in_remset_loc (p, addr, &found); if (found) @@ -883,7 +878,7 @@ sgen_ssb_find_address (char *addr) /* the freed thread ones */ for (remset = freed_thread_remsets; remset; remset = remset->next) { - DEBUG (4, fprintf (gc_debug_file, "Scanning remset for freed thread, range: %p-%p, size: %td\n", remset->data, remset->store_next, remset->store_next - remset->data)); + SGEN_LOG (4, "Scanning remset for freed thread, range: %p-%p, size: %td", remset->data, remset->store_next, remset->store_next - remset->data); for (p = remset->data; p < remset->store_next;) { p = find_in_remset_loc (p, addr, &found); if (found) @@ -894,7 +889,6 @@ sgen_ssb_find_address (char *addr) return FALSE; } - void sgen_ssb_init (SgenRemeberedSet *remset) { @@ -941,4 +935,16 @@ sgen_ssb_init (SgenRemeberedSet *remset) remset->find_address = sgen_ssb_find_address; } -#endif + +#else + +void +sgen_ssb_init (SgenRemeberedSet *remset) +{ + fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_wbarrier.\n"); + exit (1); +} + +#endif /* DISABLE_SGEN_REMSET */ + +#endif /* HAVE_SGEN_GC */ diff --git a/mono/metadata/sgen-stw.c b/mono/metadata/sgen-stw.c index 6a1238ab869..0e870e97c8d 100644 --- a/mono/metadata/sgen-stw.c +++ b/mono/metadata/sgen-stw.c @@ -8,25 +8,20 @@ * Copyright 2005-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright 2011 Xamarin, Inc. + * Copyright (C) 2012 Xamarin Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" @@ -121,7 +116,7 @@ restart_threads_until_none_in_managed_allocator (void) if (!info->thread_is_dying && (!info->stack_start || info->in_critical_region || is_ip_in_managed_allocator (info->stopped_domain, info->stopped_ip))) { binary_protocol_thread_restart ((gpointer)mono_thread_info_get_tid (info)); - DEBUG (3, fprintf (gc_debug_file, "thread %p resumed.\n", (void*)info->info.native_handle)); + SGEN_LOG (3, "thread %p resumed.", (void*)info->info.native_handle); result = sgen_resume_thread (info); if (result) { ++restart_count; @@ -224,7 +219,7 @@ sgen_stop_world (int generation) update_current_thread_stack (&count); sgen_global_stop_count++; - DEBUG (3, fprintf (gc_debug_file, "stopping world n %d from %p %p\n", sgen_global_stop_count, mono_thread_info_current (), (gpointer)mono_native_thread_id_get ())); + SGEN_LOG (3, "stopping world n %d from %p %p", sgen_global_stop_count, mono_thread_info_current (), (gpointer)mono_native_thread_id_get ()); TV_GETTIME (stop_world_time); count = sgen_thread_handshake (TRUE); dead = restart_threads_until_none_in_managed_allocator (); @@ -232,7 +227,7 @@ sgen_stop_world (int generation) g_error ("More threads have died (%d) that been initialy suspended %d", dead, count); count -= dead; - DEBUG (3, fprintf (gc_debug_file, "world stopped %d thread(s)\n", count)); + SGEN_LOG (3, "world stopped %d thread(s)", count); mono_profiler_gc_event (MONO_GC_EVENT_POST_STOP_WORLD, generation); sgen_memgov_collection_start (generation); @@ -270,7 +265,7 @@ sgen_restart_world (int generation, GGTimingInfo *timing) TV_GETTIME (end_sw); usec = TV_ELAPSED (stop_world_time, end_sw); max_pause_usec = MAX (usec, max_pause_usec); - DEBUG (2, fprintf (gc_debug_file, "restarted %d thread(s) (pause time: %d usec, max: %d)\n", count, (int)usec, (int)max_pause_usec)); + SGEN_LOG (2, "restarted %d thread(s) (pause time: %d usec, max: %d)", count, (int)usec, (int)max_pause_usec); mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD, generation); bridge_process (generation); diff --git a/mono/metadata/sgen-toggleref.c b/mono/metadata/sgen-toggleref.c index ec1cb8be3e6..10f263affe5 100644 --- a/mono/metadata/sgen-toggleref.c +++ b/mono/metadata/sgen-toggleref.c @@ -1,33 +1,26 @@ /* - * * sgen-toggleref.c: toggleref support for sgen * - * Copyright 2011 Xamarin, Inc. - * * Author: * Rodrigo Kumpera (kumpera@gmail.com) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Copyright 2011 Xamarin, Inc. + * Copyright (C) 2012 Xamarin Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License 2.0 as published by the Free Software Foundation; + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License 2.0 along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "config.h" #ifdef HAVE_SGEN_GC @@ -53,7 +46,7 @@ sgen_process_togglerefs (void) int i, w; int toggle_ref_counts [3] = { 0, 0, 0 }; - DEBUG (4, fprintf (gc_debug_file, "Proccessing ToggleRefs %d\n", toggleref_array_size)); + SGEN_LOG (4, "Proccessing ToggleRefs %d", toggleref_array_size); for (i = w = 0; i < toggleref_array_size; ++i) { int res; @@ -90,11 +83,11 @@ sgen_process_togglerefs (void) toggleref_array_size = w; - DEBUG (4, fprintf (gc_debug_file, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d\n", + SGEN_LOG (4, "Done Proccessing ToggleRefs dropped %d strong %d weak %d final size %d", toggle_ref_counts [MONO_TOGGLE_REF_DROP], toggle_ref_counts [MONO_TOGGLE_REF_STRONG], toggle_ref_counts [MONO_TOGGLE_REF_WEAK], - w)); + w); } void @@ -102,13 +95,13 @@ sgen_scan_togglerefs (CopyOrMarkObjectFunc copy_func, char *start, char *end, Sg { int i; - DEBUG (4, fprintf (gc_debug_file, "Scanning ToggleRefs %d\n", toggleref_array_size)); + SGEN_LOG (4, "Scanning ToggleRefs %d", toggleref_array_size); for (i = 0; i < toggleref_array_size; ++i) { if (toggleref_array [i].strong_ref) { char *object = toggleref_array [i].strong_ref; if (object >= start && object < end) { - DEBUG (6, fprintf (gc_debug_file, "\tcopying strong slot %d\n", i)); + SGEN_LOG (6, "\tcopying strong slot %d", i); copy_func (&toggleref_array [i].strong_ref, queue); } } else if (toggleref_array [i].weak_ref) { @@ -116,10 +109,10 @@ sgen_scan_togglerefs (CopyOrMarkObjectFunc copy_func, char *start, char *end, Sg if (object >= start && object < end) { if (sgen_gc_is_object_ready_for_finalization (object)) { - DEBUG (6, fprintf (gc_debug_file, "\tcleaning weak slot %d\n", i)); + SGEN_LOG (6, "\tcleaning weak slot %d", i); toggleref_array [i].weak_ref = NULL; /* We defer compaction to only happen on the callback step. */ } else { - DEBUG (6, fprintf (gc_debug_file, "\tkeeping weak slot %d\n", i)); + SGEN_LOG (6, "\tkeeping weak slot %d", i); copy_func (&toggleref_array [i].weak_ref, queue); } } @@ -169,7 +162,7 @@ mono_gc_toggleref_add (MonoObject *object, mono_bool strong_ref) if (!toggleref_callback) return; - DEBUG (4, fprintf (gc_debug_file, "Adding toggleref %p %d\n", object, strong_ref)); + SGEN_LOG (4, "Adding toggleref %p %d", object, strong_ref); sgen_gc_lock (); diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index c71fd74a328..5a6848ea1c1 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #ifdef HAVE_SYS_TIME_H @@ -664,43 +665,22 @@ static gint32 convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level, static MonoImage *get_socket_assembly (void) { - static const char *version = NULL; - static gboolean moonlight; MonoDomain *domain = mono_domain_get (); - if (version == NULL) { - version = mono_get_runtime_info ()->framework_version; - moonlight = !strcmp (version, "2.1"); - } - if (domain->socket_assembly == NULL) { MonoImage *socket_assembly; - if (moonlight) { - socket_assembly = mono_image_loaded ("System.Net"); - if (!socket_assembly) { - MonoAssembly *sa = mono_assembly_open ("System.Net.dll", NULL); - - if (!sa) { - g_assert_not_reached (); - } else { - socket_assembly = mono_assembly_get_image (sa); - } - } - } else { - socket_assembly = mono_image_loaded ("System"); - if (!socket_assembly) { - MonoAssembly *sa = mono_assembly_open ("System.dll", NULL); - - if (!sa) { - g_assert_not_reached (); - } else { - socket_assembly = mono_assembly_get_image (sa); - } + socket_assembly = mono_image_loaded ("System"); + if (!socket_assembly) { + MonoAssembly *sa = mono_assembly_open ("System.dll", NULL); + + if (!sa) { + g_assert_not_reached (); + } else { + socket_assembly = mono_assembly_get_image (sa); } } - - domain->socket_assembly = socket_assembly; + mono_atomic_store_release (&domain->socket_assembly, socket_assembly); } return domain->socket_assembly; @@ -950,20 +930,11 @@ static MonoObject *create_object_from_sockaddr(struct sockaddr *saddr, g_assert (domain->sockaddr_data_field); } - /* Make sure there is space for the family and size bytes */ -#ifdef HAVE_SYS_UN_H - if (saddr->sa_family == AF_UNIX) { - /* sa_len includes the entire sockaddr size, so we don't need the - * N bytes (sizeof (unsigned short)) of the family. */ - data=mono_array_new_cached(domain, mono_get_byte_class (), sa_size); - } else -#endif - { - /* May be the +2 here is too conservative, as sa_len returns - * the length of the entire sockaddr_in/in6, including - * sizeof (unsigned short) of the family */ - data=mono_array_new_cached(domain, mono_get_byte_class (), sa_size+2); - } + /* May be the +2 here is too conservative, as sa_len returns + * the length of the entire sockaddr_in/in6, including + * sizeof (unsigned short) of the family */ + /* We can't really avoid the +2 as all code below depends on this size - INCLUDING unix domain sockets.*/ + data=mono_array_new_cached(domain, mono_get_byte_class (), sa_size+2); /* The data buffer is laid out as follows: * bytes 0 and 1 are the address family diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index ad2b3de06a0..85ae229e37a 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -189,7 +189,7 @@ enum { #include #ifdef HAVE_EPOLL #include -#elif defined(HAVE_KQUEUE) +#elif defined(USE_KQUEUE_FOR_THREADPOOL) #include #endif /* @@ -215,30 +215,11 @@ is_corlib_type (MonoDomain *domain, MonoClass *klass) /* * Note that we call it is_socket_type() where 'socket' refers to the image * that contains the System.Net.Sockets.Socket type. - * For moonlight there is a System.Net.Sockets.Socket class in both System.dll and System.Net.dll. */ static gboolean is_socket_type (MonoDomain *domain, MonoClass *klass) { - static const char *version = NULL; - static gboolean moonlight; - - if (is_system_type (domain, klass)) - return TRUE; - - /* If moonlight, check if the type is in System.Net.dll too */ - if (version == NULL) { - version = mono_get_runtime_info ()->framework_version; - moonlight = !strcmp (version, "2.1"); - } - - if (!moonlight) - return FALSE; - - if (domain->system_net_dll == NULL) - domain->system_net_dll = mono_image_loaded ("System.Net"); - - return klass->image == domain->system_net_dll; + return is_system_type (domain, klass); } #define check_type_cached(domain, ASSEMBLY, _class, _namespace, _name, loc) do { \ @@ -496,7 +477,7 @@ init_event_system (SocketIOData *data) data->event_system = POLL_BACKEND; } } -#elif defined(HAVE_KQUEUE) +#elif defined(USE_KQUEUE_FOR_THREADPOOL) if (data->event_system == KQUEUE_BACKEND) data->event_data = tp_kqueue_init (data); #endif @@ -525,7 +506,7 @@ socket_io_init (SocketIOData *data) data->sock_to_state = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC); #ifdef HAVE_EPOLL data->event_system = EPOLL_BACKEND; -#elif defined(HAVE_KQUEUE) +#elif defined(USE_KQUEUE_FOR_THREADPOOL) data->event_system = KQUEUE_BACKEND; #else data->event_system = POLL_BACKEND; @@ -683,7 +664,9 @@ threadpool_start_idle_threads (ThreadPool *tp) if (InterlockedCompareExchange (&tp->nthreads, n + 1, n) == n) break; } +#ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1); +#endif mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size); SleepEx (100, TRUE); } while (1); @@ -700,6 +683,7 @@ threadpool_init (ThreadPool *tp, int min_threads, int max_threads, void (*async_ MONO_SEM_INIT (&tp->new_job, 0); } +#ifndef DISABLE_PERFCOUNTERS static void * init_perf_counter (const char *category, const char *counter) { @@ -718,6 +702,7 @@ init_perf_counter (const char *category, const char *counter) machine = mono_string_new (root, "."); return mono_perfcounter_get_impl (category_str, counter_str, NULL, machine, &type, &custom); } +#endif #ifdef DEBUG static void @@ -856,6 +841,7 @@ mono_thread_pool_init () wsqs = g_ptr_array_sized_new (MAX (100 * cpu_count, thread_count)); mono_wsq_init (); +#ifndef DISABLE_PERFCOUNTERS async_tp.pc_nitems = init_perf_counter ("Mono Threadpool", "Work Items Added"); g_assert (async_tp.pc_nitems); @@ -867,6 +853,7 @@ mono_thread_pool_init () async_io_tp.pc_nthreads = init_perf_counter ("Mono Threadpool", "# of IO Threads"); g_assert (async_io_tp.pc_nthreads); +#endif tp_inited = 2; #ifdef DEBUG signal (SIGALRM, signal_handler); @@ -1019,7 +1006,9 @@ threadpool_start_thread (ThreadPool *tp) stack_size = (!tp->is_io) ? 0 : SMALL_STACK; while (!mono_runtime_is_shutting_down () && (n = tp->nthreads) < tp->max_threads) { if (InterlockedCompareExchange (&tp->nthreads, n + 1, n) == n) { +#ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1); +#endif mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size); return TRUE; } @@ -1077,7 +1066,9 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs) o->add_time = mono_100ns_ticks (); } threadpool_jobs_inc (ar); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nitems, TRUE, 1); +#endif if (!tp->is_io && mono_wsq_local_push (ar)) continue; @@ -1545,7 +1536,9 @@ async_invoke_thread (gpointer data) if (!down && nt <= tp->min_threads) break; if (down || InterlockedCompareExchange (&tp->nthreads, nt - 1, nt) == nt) { +#ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nthreads, TRUE, -1); +#endif if (!tp->is_io) { remove_wsq (wsq); } diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 0b1d72f05b7..2e05a935793 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -1362,6 +1362,44 @@ gboolean ves_icall_System_Threading_Thread_Join_internal(MonoInternalThread *thi return(FALSE); } +static gint32 +mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32 numhandles, gpointer *handles, gboolean waitall, gint32 ms, gboolean alertable) +{ + MonoException *exc; + guint32 ret; + gint64 start; + gint32 diff_ms; + gint32 wait = ms; + + start = (ms == -1) ? 0 : mono_100ns_ticks (); + do { + if (multiple) + ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable); + else + ret = WaitForSingleObjectEx (handles [0], ms, alertable); + + if (ret != WAIT_IO_COMPLETION) + break; + + exc = mono_thread_execute_interruption (thread); + if (exc) + mono_raise_exception (exc); + + if (ms == -1) + continue; + + /* Re-calculate ms according to the time passed */ + diff_ms = (mono_100ns_ticks () - start) / 10000; + if (diff_ms >= ms) { + ret = WAIT_TIMEOUT; + break; + } + wait = ms - diff_ms; + } while (TRUE); + + return ret; +} + /* FIXME: exitContext isnt documented */ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext) { @@ -1389,7 +1427,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_ mono_thread_set_state (thread, ThreadState_WaitSleepJoin); - ret=WaitForMultipleObjectsEx(numhandles, handles, TRUE, ms, TRUE); + ret = mono_wait_uninterrupted (thread, TRUE, numhandles, handles, TRUE, ms, TRUE); mono_thread_clr_state (thread, ThreadState_WaitSleepJoin); @@ -1398,12 +1436,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_ if(ret==WAIT_FAILED) { THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, GetCurrentThreadId ())); return(FALSE); - } else if(ret==WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION) { - /* Do we want to try again if we get - * WAIT_IO_COMPLETION? The documentation for - * WaitHandle doesn't give any clues. (We'd have to - * fiddle with the timeout if we retry.) - */ + } else if(ret==WAIT_TIMEOUT) { THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, GetCurrentThreadId ())); return(FALSE); } @@ -1420,7 +1453,6 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha guint32 i; MonoObject *waitHandle; MonoInternalThread *thread = mono_thread_internal_current (); - guint32 start; /* Do this WaitSleepJoin check before creating objects */ mono_thread_current_check_pending_interrupt (); @@ -1440,20 +1472,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha mono_thread_set_state (thread, ThreadState_WaitSleepJoin); - start = (ms == -1) ? 0 : mono_msec_ticks (); - do { - ret = WaitForMultipleObjectsEx (numhandles, handles, FALSE, ms, TRUE); - if (ret != WAIT_IO_COMPLETION) - break; - if (ms != -1) { - guint32 diff; - - diff = mono_msec_ticks () - start; - ms -= diff; - if (ms <= 0) - break; - } - } while (ms == -1 || ms > 0); + ret = mono_wait_uninterrupted (thread, TRUE, numhandles, handles, FALSE, ms, TRUE); mono_thread_clr_state (thread, ThreadState_WaitSleepJoin); @@ -1489,19 +1508,14 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this mono_thread_set_state (thread, ThreadState_WaitSleepJoin); - ret=WaitForSingleObjectEx (handle, ms, TRUE); + ret = mono_wait_uninterrupted (thread, FALSE, 1, &handle, FALSE, ms, TRUE); mono_thread_clr_state (thread, ThreadState_WaitSleepJoin); if(ret==WAIT_FAILED) { THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, GetCurrentThreadId ())); return(FALSE); - } else if(ret==WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION) { - /* Do we want to try again if we get - * WAIT_IO_COMPLETION? The documentation for - * WaitHandle doesn't give any clues. (We'd have to - * fiddle with the timeout if we retry.) - */ + } else if(ret==WAIT_TIMEOUT) { THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, GetCurrentThreadId ())); return(FALSE); } diff --git a/mono/mini/Makefile.am b/mono/mini/Makefile.am index 148ffbcbcb3..990804f4306 100644 --- a/mono/mini/Makefile.am +++ b/mono/mini/Makefile.am @@ -112,9 +112,13 @@ endif noinst_PROGRAMS = genmdesc +if DISABLE_EXECUTABLES +shared_libraries = $(boehm_libraries) $(sgen_libraries) +else if SHARED_MONO shared_libraries = $(boehm_libraries) $(sgen_libraries) endif +endif lib_LTLIBRARIES = $(shared_libraries) diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index ee8834a56ee..964f5e69012 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -125,6 +125,7 @@ typedef struct MonoAotOptions { gboolean log_generics; gboolean direct_pinvoke; gboolean direct_icalls; + gboolean no_direct_calls; int nthreads; int ntrampolines; int nrgctx_trampolines; @@ -217,6 +218,10 @@ typedef struct MonoAotCompile { GHashTable *plt_entry_debug_sym_cache; gboolean thumb_mixed, need_no_dead_strip, need_pt_gnu_stack; GHashTable *ginst_hash; + gboolean global_symbols; +#ifdef MONOTOUCH + gboolean direct_method_addresses; +#endif } MonoAotCompile; typedef struct { @@ -609,6 +614,11 @@ arch_init (MonoAotCompile *acfg) #if defined(__linux__) && !defined(TARGET_ARM) acfg->need_pt_gnu_stack = TRUE; #endif + +#ifdef MONOTOUCH + acfg->direct_method_addresses = TRUE; + acfg->global_symbols = TRUE; +#endif } /* @@ -3703,7 +3713,7 @@ is_direct_callable (MonoAotCompile *acfg, MonoMethod *method, MonoJumpInfo *patc // FIXME: Maybe call the wrapper directly ? direct_callable = FALSE; - if (acfg->aot_opts.soft_debug) { + if (acfg->aot_opts.soft_debug || acfg->aot_opts.no_direct_calls) { /* Disable this so all calls go through load_method (), see the * mini_get_debug_options ()->load_aot_jit_info_eagerly = TRUE; line in * mono_debugger_agent_init (). @@ -3773,7 +3783,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui MonoMethodHeader *header; gboolean skip, direct_call; guint32 got_slot; - char direct_call_target [1024]; + const char *direct_call_target; const char *direct_pinvoke; if (method) { @@ -3826,8 +3836,9 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui MonoCompile *callee_cfg = g_hash_table_lookup (acfg->method_to_cfg, patch_info->data.method); //printf ("DIRECT: %s %s\n", method ? mono_method_full_name (method, TRUE) : "", mono_method_full_name (callee_cfg->method, TRUE)); direct_call = TRUE; - g_assert (strlen (callee_cfg->asm_symbol) < 1000); - sprintf (direct_call_target, "%s", callee_cfg->asm_symbol); + direct_call_target = callee_cfg->asm_symbol; + patch_info->type = MONO_PATCH_INFO_NONE; + acfg->stats.direct_calls ++; } acfg->stats.all_calls ++; @@ -3846,7 +3857,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui #endif direct_call = TRUE; g_assert (strlen (direct_pinvoke) < 1000); - sprintf (direct_call_target, "%s%s", prefix, direct_pinvoke); + direct_call_target = g_strdup_printf ("%s%s", prefix, direct_pinvoke); } } } @@ -3861,7 +3872,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui if (plt_entry) { /* This patch has a PLT entry, so we must emit a call to the PLT entry */ direct_call = TRUE; - sprintf (direct_call_target, "%s", plt_entry->symbol); + direct_call_target = plt_entry->symbol; /* Nullify the patch */ patch_info->type = MONO_PATCH_INFO_NONE; @@ -3969,7 +3980,7 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) int method_index; guint8 *code; char *debug_sym = NULL; - char symbol [128]; + char *symbol = NULL; int func_alignment = AOT_FUNC_ALIGNMENT; MonoMethodHeader *header; char *export_name; @@ -3979,15 +3990,19 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) header = cfg->header; method_index = get_method_index (acfg, method); + symbol = g_strdup_printf ("%sme_%x", acfg->temp_prefix, method_index); - /* Make the labels local */ - sprintf (symbol, "%s", cfg->asm_symbol); + /* Make the labels local */ emit_section_change (acfg, ".text", 0); emit_alignment (acfg, func_alignment); - emit_label (acfg, symbol); + + if (acfg->global_symbols && acfg->need_no_dead_strip) + fprintf (acfg->fp, " .no_dead_strip %s\n", cfg->asm_symbol); + + emit_label (acfg, cfg->asm_symbol); - if (acfg->aot_opts.write_symbols) { + if (acfg->aot_opts.write_symbols && !acfg->global_symbols) { /* * Write a C style symbol for every method, this has two uses: * - it works on platforms where the dwarf debugging info is not @@ -3996,7 +4011,6 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) */ debug_sym = get_debug_sym (method, "", acfg->method_label_hash); - sprintf (symbol, "%sme_%x", acfg->temp_prefix, method_index); if (acfg->need_no_dead_strip) fprintf (acfg->fp, " .no_dead_strip %s\n", debug_sym); emit_local_symbol (acfg, debug_sym, symbol, TRUE); @@ -4011,7 +4025,7 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) } if (cfg->verbose_level > 0) - g_print ("Method %s emitted as %s\n", mono_method_full_name (method, TRUE), symbol); + g_print ("Method %s emitted as %s\n", mono_method_full_name (method, TRUE), cfg->asm_symbol); acfg->stats.code_size += cfg->code_len; @@ -4026,8 +4040,8 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg) g_free (debug_sym); } - sprintf (symbol, "%sme_%x", acfg->temp_prefix, method_index); emit_label (acfg, symbol); + g_free (symbol); } /** @@ -5246,6 +5260,12 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) opts->direct_pinvoke = TRUE; } else if (str_begins_with (arg, "direct-icalls")) { opts->direct_icalls = TRUE; +#if defined(TARGET_ARM) + } else if (str_begins_with (arg, "iphone-abi")) { + // older full-aot users did depend on this. +#endif + } else if (str_begins_with (arg, "no-direct-calls")) { + opts->no_direct_calls = TRUE; } else if (str_begins_with (arg, "print-skipped")) { opts->print_skipped_methods = TRUE; } else if (str_begins_with (arg, "stats")) { @@ -5872,7 +5892,7 @@ mono_aot_patch_info_dup (MonoJumpInfo* ji) static void emit_llvm_file (MonoAotCompile *acfg) { - char *command, *opts; + char *command, *opts, *tempbc; int i; MonoJumpInfo *patch_info; @@ -5906,7 +5926,7 @@ emit_llvm_file (MonoAotCompile *acfg) */ if (strcmp (acfg->image->assembly->aname.name, "mscorlib") == 0) { /* For the generic + rgctx trampolines */ - acfg->final_got_size += 200; + acfg->final_got_size += 400; /* For the specific trampolines */ for (ntype = 0; ntype < MONO_AOT_TRAMP_NUM; ++ntype) acfg->final_got_size += acfg->num_trampolines [ntype] * 2; @@ -5914,7 +5934,9 @@ emit_llvm_file (MonoAotCompile *acfg) } - mono_llvm_emit_aot_module ("temp.bc", acfg->final_got_size); + tempbc = g_strdup_printf ("%s.bc", acfg->tmpfname); + mono_llvm_emit_aot_module (tempbc, acfg->final_got_size); + g_free (tempbc); /* * FIXME: Experiment with adding optimizations, the -std-compile-opts set takes @@ -5933,7 +5955,7 @@ emit_llvm_file (MonoAotCompile *acfg) opts = g_strdup ("-instcombine -simplifycfg"); opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -simplifycfg -preverify -domtree -verify"); #if 1 - command = g_strdup_printf ("%sopt -f %s -o temp.opt.bc temp.bc", acfg->aot_opts.llvm_path, opts); + command = g_strdup_printf ("%sopt -f %s -o %s.opt.bc %s.bc", acfg->aot_opts.llvm_path, opts, acfg->tmpfname, acfg->tmpfname); printf ("Executing opt: %s\n", command); if (system (command) != 0) { exit (1); @@ -5956,7 +5978,7 @@ emit_llvm_file (MonoAotCompile *acfg) g_string_append_printf (acfg->llc_args, " -relocation-model=pic"); unlink (acfg->tmpfname); - command = g_strdup_printf ("%sllc %s -disable-gnu-eh-frame -enable-mono-eh-frame -o %s temp.opt.bc", acfg->aot_opts.llvm_path, acfg->llc_args->str, acfg->tmpfname); + command = g_strdup_printf ("%sllc %s -disable-gnu-eh-frame -enable-mono-eh-frame -o %s %s.opt.bc", acfg->aot_opts.llvm_path, acfg->llc_args->str, acfg->tmpfname, acfg->tmpfname); printf ("Executing llc: %s\n", command); @@ -6074,6 +6096,46 @@ emit_code (MonoAotCompile *acfg) } } +#ifdef MONOTOUCH + if (acfg->direct_method_addresses) { + acfg->flags |= MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES; + + sprintf (symbol, "method_addresses"); + emit_section_change (acfg, RODATA_SECT, 1); + emit_alignment (acfg, 8); + emit_label (acfg, symbol); + + for (i = 0; i < acfg->nmethods; ++i) { + if (acfg->cfgs [i]) { + emit_pointer (acfg, acfg->cfgs [i]->asm_symbol); + } else { + emit_pointer (acfg, NULL); + } + } + + /* Empty */ + sprintf (symbol, "code_offsets"); + emit_section_change (acfg, RODATA_SECT, 1); + emit_alignment (acfg, 8); + emit_label (acfg, symbol); + } else { + sprintf (symbol, "code_offsets"); + emit_section_change (acfg, RODATA_SECT, 1); + emit_alignment (acfg, 8); + emit_label (acfg, symbol); + + acfg->stats.offsets_size += acfg->nmethods * 4; + + sprintf (end_symbol, "methods"); + for (i = 0; i < acfg->nmethods; ++i) { + if (acfg->cfgs [i]) { + emit_symbol_diff (acfg, acfg->cfgs [i]->asm_symbol, end_symbol, 0); + } else { + emit_int32 (acfg, 0xffffffff); + } + } + } +#else sprintf (symbol, "code_offsets"); emit_section_change (acfg, RODATA_SECT, 1); emit_alignment (acfg, 8); @@ -6089,6 +6151,7 @@ emit_code (MonoAotCompile *acfg) emit_int32 (acfg, 0xffffffff); } } +#endif emit_line (acfg); /* Emit a sorted table mapping methods to their unbox trampolines */ @@ -6997,6 +7060,9 @@ emit_file_info (MonoAotCompile *acfg) emit_pointer (acfg, "method_info_offsets"); emit_pointer (acfg, "ex_info_offsets"); emit_pointer (acfg, "code_offsets"); +#ifdef MONOTOUCH + emit_pointer (acfg, "method_addresses"); +#endif emit_pointer (acfg, "extra_method_info_offsets"); emit_pointer (acfg, "extra_method_table"); emit_pointer (acfg, "got_info_offsets"); @@ -7048,20 +7114,22 @@ emit_file_info (MonoAotCompile *acfg) emit_int32 (acfg, acfg->trampoline_size [i]); #if defined (TARGET_ARM) && defined (TARGET_MACH) - { - MonoType t; - int align = 0; + { + MonoType t; + int align = 0; - t.type = MONO_TYPE_R8; - mono_type_size (&t, &align); + memset (&t, 0, sizeof (MonoType)); + t.type = MONO_TYPE_R8; + mono_type_size (&t, &align); - emit_int32 (acfg, align); + emit_int32 (acfg, align); - t.type = MONO_TYPE_I8; - mono_type_size (&t, &align); + memset (&t, 0, sizeof (MonoType)); + t.type = MONO_TYPE_I8; + mono_type_size (&t, &align); - emit_int32 (acfg, align); - } + emit_int32 (acfg, align); + } #else emit_int32 (acfg, __alignof__ (double)); emit_int32 (acfg, __alignof__ (gint64)); @@ -7112,7 +7180,7 @@ emit_dwarf_info (MonoAotCompile *acfg) { #ifdef EMIT_DWARF_INFO int i; - char symbol [128], symbol2 [128]; + char symbol2 [128]; /* DIEs for methods */ for (i = 0; i < acfg->nmethods; ++i) { @@ -7125,10 +7193,9 @@ emit_dwarf_info (MonoAotCompile *acfg) if (cfg->compile_llvm) continue; - sprintf (symbol, "%s", cfg->asm_symbol); sprintf (symbol2, "%sme_%x", acfg->temp_prefix, i); - mono_dwarf_writer_emit_method (acfg->dwarf, cfg, cfg->method, symbol, symbol2, cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, mono_debug_find_method (cfg->jit_info->method, mono_domain_get ())); + mono_dwarf_writer_emit_method (acfg->dwarf, cfg, cfg->method, cfg->asm_symbol, symbol2, cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, mono_debug_find_method (cfg->jit_info->method, mono_domain_get ())); } #endif } @@ -7694,6 +7761,8 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) if (COMPILE_LLVM (cfg)) cfg->asm_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, cfg->llvm_method_name); + else if (acfg->global_symbols) + cfg->asm_symbol = get_debug_sym (cfg->method, "", acfg->method_label_hash); else cfg->asm_symbol = g_strdup_printf ("%s%sm_%x", acfg->temp_prefix, acfg->llvm_label_prefix, method_index); } diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 0a51626141d..2f67e93ec11 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -98,6 +98,9 @@ typedef struct MonoAotModule { guint8 *plt_end; guint8 *blob; gint32 *code_offsets; +#ifdef MONOTOUCH + gpointer *method_addresses; +#endif /* This contains pairs sorted by offset */ /* This is needed because LLVM emitted methods can be in any order */ gint32 *sorted_code_offsets; @@ -1568,6 +1571,9 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) } amodule->code_offsets = info->code_offsets; +#ifdef MONOTOUCH + amodule->method_addresses = info->method_addresses; +#endif amodule->code = info->methods; #ifdef TARGET_ARM /* Mask out thumb interop bit */ @@ -1594,6 +1600,19 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK] = info->imt_thunks; amodule->thumb_end = info->thumb_end; +#ifdef MONOTOUCH + if (info->flags & MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES) { + /* Compute code_offsets from the method addresses */ + amodule->code_offsets = g_malloc0 (amodule->info.nmethods * sizeof (gint32)); + for (i = 0; i < amodule->info.nmethods; ++i) { + if (!amodule->method_addresses [i]) + amodule->code_offsets [i] = 0xffffffff; + else + amodule->code_offsets [i] = (char*)amodule->method_addresses [i] - (char*)amodule->code; + } + } +#endif + if (make_unreadable) { #ifndef TARGET_WIN32 guint8 *addr; @@ -2956,7 +2975,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)]; - if (amodule->thumb_end && code < amodule->thumb_end) { + if (amodule->thumb_end && code < amodule->thumb_end && ((amodule->info.flags & MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES) == 0)) { /* Convert this into a thumb address */ g_assert ((amodule->code_offsets [method_index] & 0x1) == 0); code = &amodule->code [amodule->code_offsets [method_index] + 1]; @@ -3653,10 +3672,23 @@ mono_aot_get_plt_entry (guint8 *code) g_assert_not_reached (); #endif +#ifdef MONOTOUCH + while (target != NULL) { + if ((target >= (guint8*)(amodule->plt)) && (target < (guint8*)(amodule->plt_end))) + return target; + + // Add 4 since mono_arch_get_call_target assumes we're passing + // the instruction after the actual branch instruction. + target = mono_arch_get_call_target (target + 4); + } + + return NULL; +#else if ((target >= (guint8*)(amodule->plt)) && (target < (guint8*)(amodule->plt_end))) return target; else return NULL; +#endif } /* @@ -3869,9 +3901,16 @@ get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotM *out_amodule = amodule; - if (amodule->trampoline_index [tramp_type] == amodule->info.num_trampolines [tramp_type]) - g_error ("Ran out of trampolines of type %d in '%s' (%d)\n", tramp_type, image->name, amodule->info.num_trampolines [tramp_type]); - + if (amodule->trampoline_index [tramp_type] == amodule->info.num_trampolines [tramp_type]) { + g_error ("Ran out of trampolines of type %d in '%s' (%d)%s\n", + tramp_type, image->name, amodule->info.num_trampolines [tramp_type], +#ifdef MONOTOUCH + ". See http://docs.xamarin.com/ios/troubleshooting for instruction on how to fix this condition" +#else + "" +#endif + ); + } index = amodule->trampoline_index [tramp_type] ++; mono_aot_unlock (); diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 2c47fa81502..080b8826321 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -80,6 +80,15 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, #include "debugger-agent.h" #include "mini.h" +/* +On iOS we can't use System.Environment.Exit () as it will do the wrong +shutdown sequence. +*/ +#if !defined (TARGET_IOS) +#define TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT +#endif + + #ifndef MONO_ARCH_SOFT_DEBUG_SUPPORTED #define DISABLE_DEBUGGER_AGENT 1 #endif @@ -1376,6 +1385,15 @@ static DebuggerTransport *transport; static DebuggerTransport transports [MAX_TRANSPORTS]; static int ntransports; +void +mono_debugger_agent_register_transport (DebuggerTransport *trans); + +void +mono_debugger_agent_register_transport (DebuggerTransport *trans) +{ + register_transport (trans); +} + static void register_transport (DebuggerTransport *trans) { @@ -1438,6 +1456,12 @@ transport_recv (void *buf, int len) return transport->recv (buf, len); } +gboolean +mono_debugger_agent_transport_handshake (void) +{ + return transport_handshake (); +} + static gboolean transport_handshake (void) { @@ -2536,13 +2560,19 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) MonoJitInfo *ji; info = mono_thread_info_safe_suspend_sync ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE); - g_assert (info); - - ji = mono_jit_info_table_find (info->suspend_state.unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&info->suspend_state.ctx)); + if (!info) { + DEBUG(1, fprintf (log_file, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid)); + /* + * Attached thread which died without detaching. + */ + tls->terminated = TRUE; + } else { + ji = mono_jit_info_table_find (info->suspend_state.unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&info->suspend_state.ctx)); - thread_interrupt (tls, info, NULL, ji); + thread_interrupt (tls, info, NULL, ji); - mono_thread_info_resume (mono_thread_info_get_tid (info)); + mono_thread_info_resume (mono_thread_info_get_tid (info)); + } } else { res = mono_thread_kill (thread, mono_thread_get_abort_signal ()); if (res) { @@ -5095,13 +5125,35 @@ mono_debugger_agent_debug_log_is_enabled (void) return agent_config.enabled; } +#ifdef PLATFORM_ANDROID +void +mono_debugger_agent_unhandled_exception (MonoException *exc) +{ + int suspend_policy; + GSList *events; + EventInfo ei; + + if (!inited) + return; + + memset (&ei, 0, sizeof (EventInfo)); + ei.exc = (MonoObject*)exc; + + mono_loader_lock (); + events = create_event_list (EVENT_KIND_EXCEPTION, NULL, NULL, &ei, &suspend_policy); + mono_loader_unlock (); + + process_event (EVENT_KIND_EXCEPTION, &ei, 0, NULL, events, suspend_policy); +} +#endif + void mono_debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx) { - int suspend_policy; + int i, j, suspend_policy; GSList *events; - MonoJitInfo *ji; + MonoJitInfo *ji, *catch_ji; EventInfo ei; DebuggerTlsData *tls = NULL; @@ -5164,15 +5216,45 @@ mono_debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx return; ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (throw_ctx), NULL); + if (catch_ctx) + catch_ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (catch_ctx), NULL); + else + catch_ji = NULL; ei.exc = (MonoObject*)exc; ei.caught = catch_ctx != NULL; mono_loader_lock (); + + /* Treat exceptions which are caught in non-user code as unhandled */ + for (i = 0; i < event_requests->len; ++i) { + EventRequest *req = g_ptr_array_index (event_requests, i); + if (req->event_kind != EVENT_KIND_EXCEPTION) + continue; + + for (j = 0; j < req->nmodifiers; ++j) { + Modifier *mod = &req->modifiers [j]; + + if (mod->kind == MOD_KIND_ASSEMBLY_ONLY && catch_ji) { + int k; + gboolean found = FALSE; + MonoAssembly **assemblies = mod->data.assemblies; + + if (assemblies) { + for (k = 0; assemblies [k]; ++k) + if (assemblies [k] == catch_ji->method->klass->image->assembly) + found = TRUE; + } + if (!found) + ei.caught = FALSE; + } + } + } + events = create_event_list (EVENT_KIND_EXCEPTION, NULL, ji, &ei, &suspend_policy); mono_loader_unlock (); - if (tls && catch_ctx) { + if (tls && ei.caught && catch_ctx) { tls->catch_ctx = *catch_ctx; tls->has_catch_ctx = TRUE; } @@ -6278,9 +6360,11 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) suspend_vm (); wait_for_suspend (); +#ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT env_class = mono_class_from_name (mono_defaults.corlib, "System", "Environment"); if (env_class) exit_method = mono_class_get_method_from_name (env_class, "Exit", 1); +#endif mono_loader_lock (); thread = mono_g_hash_table_find (tid_to_thread, is_really_suspended, NULL); @@ -8574,8 +8658,10 @@ debugger_thread (void *arg) res = transport_recv (header, HEADER_LENGTH); /* This will break if the socket is closed during shutdown too */ - if (res != HEADER_LENGTH) + if (res != HEADER_LENGTH) { + DEBUG (1, fprintf (log_file, "[dbg] transport_recv () returned %d, expected %d.\n", res, HEADER_LENGTH)); break; + } p = header; end = header + HEADER_LENGTH; @@ -8605,8 +8691,10 @@ debugger_thread (void *arg) if (len - HEADER_LENGTH > 0) { res = transport_recv (data, len - HEADER_LENGTH); - if (res != len - HEADER_LENGTH) + if (res != len - HEADER_LENGTH) { + DEBUG (1, fprintf (log_file, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH)); break; + } } p = data; diff --git a/mono/mini/debugger-agent.h b/mono/mini/debugger-agent.h index cc0a2b97804..7a7b9473a03 100644 --- a/mono/mini/debugger-agent.h +++ b/mono/mini/debugger-agent.h @@ -30,6 +30,11 @@ mono_debugger_agent_free_domain_info (MonoDomain *domain) MONO_INTERNAL; gboolean mono_debugger_agent_thread_interrupt (void *sigctx, MonoJitInfo *ji) MONO_INTERNAL; +#ifdef PLATFORM_ANDROID +void +mono_debugger_agent_unhandled_exception (MonoException *exc); +#endif + void mono_debugger_agent_handle_exception (MonoException *ext, MonoContext *throw_ctx, MonoContext *catch_ctx) MONO_INTERNAL; @@ -48,4 +53,7 @@ mono_debugger_agent_debug_log (int level, MonoString *category, MonoString *mess gboolean mono_debugger_agent_debug_log_is_enabled (void) MONO_INTERNAL; +gboolean +mono_debugger_agent_transport_handshake (void) MONO_INTERNAL; + #endif diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index f0cfe10d088..60bbfd4e93b 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -449,7 +449,9 @@ static int compile_unit_attr [] = { static int subprogram_attr [] = { DW_AT_name , DW_FORM_string, +#ifndef TARGET_IOS DW_AT_description , DW_FORM_string, +#endif DW_AT_low_pc , DW_FORM_addr, DW_AT_high_pc , DW_FORM_addr, DW_AT_frame_base , DW_FORM_block1 @@ -457,7 +459,9 @@ static int subprogram_attr [] = { static int tramp_subprogram_attr [] = { DW_AT_name , DW_FORM_string, +#ifndef TARGET_IOS DW_AT_description , DW_FORM_string, +#endif DW_AT_low_pc , DW_FORM_addr, DW_AT_high_pc , DW_FORM_addr, }; @@ -1909,7 +1913,9 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod emit_uleb128 (w, ABBREV_SUBPROGRAM); name = mono_method_full_name (method, FALSE); emit_string (w, name); +#ifndef TARGET_IOS emit_string (w, name); +#endif g_free (name); if (start_symbol) { emit_pointer_unaligned (w, start_symbol); diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index dc2cbb3f445..a8c8c0f2bd4 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -627,7 +627,7 @@ get_throw_trampoline (const char *name, gboolean rethrow, gboolean llvm, gboolea code = mono_arch_emit_load_aotconst (start, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, corlib ? "mono_x86_throw_corlib_exception" : "mono_x86_throw_exception"); x86_call_reg (code, X86_EAX); } else { - x86_call_code (code, resume_unwind ? (mono_x86_resume_unwind) : (corlib ? (gpointer)mono_x86_throw_corlib_exception : (gpointer)mono_x86_throw_exception)); + x86_call_code (code, resume_unwind ? (gpointer)(mono_x86_resume_unwind) : (corlib ? (gpointer)mono_x86_throw_corlib_exception : (gpointer)mono_x86_throw_exception)); } x86_breakpoint (code); @@ -867,6 +867,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Pop arguments off the stack */ /* FIXME: Handle the delegate case too ((*lmf)->method == NULL) */ /* FIXME: Handle the IMT/vtable case too */ +#if 0 #ifndef ENABLE_LLVM if ((*lmf)->method) { MonoMethod *method = (*lmf)->method; @@ -875,6 +876,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, guint32 stack_to_pop = mono_arch_get_argument_info (NULL, mono_method_signature (method), mono_method_signature (method)->param_count, arg_info); new_ctx->esp += stack_to_pop; } +#endif #endif } else diff --git a/mono/mini/iltests.il.in b/mono/mini/iltests.il.in index c847d2d609c..8ea5c06d27d 100644 --- a/mono/mini/iltests.il.in +++ b/mono/mini/iltests.il.in @@ -2602,6 +2602,13 @@ END: ret } + .method public static default int32 test_1_sizeof_ref () cil managed { + call int32 Tests::SizeOfT() + sizeof [mscorlib]System.IntPtr + ceq + ret + } + .field static public int32 volatile_int .method public static default int32 test_5_volatile_load_store () cil managed { diff --git a/mono/mini/mdb-debug-info32-darwin.s b/mono/mini/mdb-debug-info32-darwin.s index d7cb2cbc82d..5d80af79fd5 100644 --- a/mono/mini/mdb-debug-info32-darwin.s +++ b/mono/mini/mdb-debug-info32-darwin.s @@ -10,4 +10,5 @@ _MONO_DEBUGGER__notification_function: _MONO_DEBUGGER__debugger_info_ptr: .long _MONO_DEBUGGER__debugger_info _MONO_DEBUGGER__using_debugger: - .quad 0 + .long 0 + .long 0 diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 4df5f0af05a..3ca8845118b 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -5990,6 +5990,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b init_locals = header->init_locals; seq_points = cfg->gen_seq_points && cfg->method == method; +#ifdef PLATFORM_ANDROID + seq_points &= cfg->method->wrapper_type == MONO_WRAPPER_NONE; +#endif if (cfg->gen_seq_points && cfg->method == method) { minfo = mono_debug_lookup_method (method); @@ -10088,6 +10091,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b token = read32 (ip + 2); func = mono_method_get_wrapper_data (method, token); info = mono_find_jit_icall_by_addr (func); + if (!info) + g_error ("Could not find icall address in wrapper %s", mono_method_full_name (method, 1)); g_assert (info); CHECK_STACK (info->sig->param_count); @@ -10844,7 +10849,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b break; } case CEE_SIZEOF: { - guint32 align; + guint32 val; int ialign; CHECK_STACK_OVF (1); @@ -10852,14 +10857,14 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b token = read32 (ip + 2); if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC && !method->klass->image->dynamic && !generic_context) { MonoType *type = mono_type_create_from_typespec (image, token); - token = mono_type_size (type, &ialign); + val = mono_type_size (type, &ialign); } else { MonoClass *klass = mono_class_get_full (image, token, generic_context); CHECK_TYPELOAD (klass); mono_class_init (klass); - token = mono_class_value_size (klass, &align); + val = mono_type_size (&klass->byval_arg, &ialign); } - EMIT_NEW_ICONST (cfg, ins, token); + EMIT_NEW_ICONST (cfg, ins, val); *sp++= ins; ip += 6; break; diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index 0a9cd51a8de..84e6bfd0c99 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -387,6 +387,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_GC_MAPS_SUPPORTED 1 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1 +#define MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK 1 gboolean mono_amd64_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL; diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index 762a178c195..5d29dd4144c 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -53,6 +53,10 @@ #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) +#if __APPLE__ +void sys_icache_invalidate (void *start, size_t len); +#endif + static gint lmf_tls_offset = -1; static gint lmf_addr_tls_offset = -1; diff --git a/mono/mini/mini-darwin.c b/mono/mini/mini-darwin.c index 027b0872049..5ec06d20a74 100644 --- a/mono/mini/mini-darwin.c +++ b/mono/mini/mini-darwin.c @@ -69,7 +69,7 @@ #include #include -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5) && !defined (TARGET_ARM) +#if defined (TARGET_OSX) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5) #define NEEDS_EXCEPTION_THREAD #endif @@ -307,7 +307,7 @@ mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoNativeThrea mono_sigctx_to_monoctx (&ctx, &tctx->ctx); - domain_key = mono_domain_get_tls_offset (); + domain_key = mono_domain_get_tls_key (); jit_key = mono_get_jit_tls_key (); jit_tls = mono_mach_arch_get_tls_value_from_thread (thread_id, jit_key); diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 76414e7691e..86dc4340937 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "mini.h" #include "debug-mini.h" @@ -1366,7 +1367,9 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3 if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) { gboolean is_user_frame = ji->method->wrapper_type == MONO_WRAPPER_NONE || ji->method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->exceptions_filters++; +#endif mono_debugger_call_exception_handler (ei->data.filter, MONO_CONTEXT_GET_SP (ctx), ex_obj); /* @@ -1560,7 +1563,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume, mono_debugger_agent_handle_exception (obj, ctx, NULL); if (mini_get_debug_options ()->suspend_on_unhandled) { - fprintf (stderr, "Unhandled exception, suspending..."); + mono_runtime_printf_err ("Unhandled exception, suspending..."); while (1) ; } @@ -1723,7 +1726,9 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume, mono_debugger_call_exception_handler (ei->handler_start, MONO_CONTEXT_GET_SP (ctx), ex_obj); MONO_CONTEXT_SET_IP (ctx, ei->handler_start); *(mono_get_lmf_addr ()) = lmf; +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->exceptions_depth += frame_count; +#endif if (obj == domain->stack_overflow_ex) jit_tls->handling_stack_ovf = FALSE; @@ -1747,7 +1752,9 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume, mono_profiler_exception_clause_handler (ji->method, ei->flags, i); jit_tls->orig_ex_ctx_set = FALSE; mono_debugger_call_exception_handler (ei->handler_start, MONO_CONTEXT_GET_SP (ctx), ex_obj); +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->exceptions_finallys++; +#endif *(mono_get_lmf_addr ()) = lmf; if (ji->from_llvm) { /* @@ -1900,7 +1907,9 @@ mono_debugger_run_finally (MonoContext *start_ctx) gboolean mono_handle_exception (MonoContext *ctx, gpointer obj) { +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->exceptions_thrown++; +#endif return mono_handle_exception_internal (ctx, obj, FALSE, NULL); } @@ -2084,7 +2093,7 @@ mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, /* We print a message: after this even managed stack overflows * may crash the runtime */ - fprintf (stderr, "Stack overflow in unmanaged: IP: %p, fault addr: %p\n", mono_arch_ip_from_context (ctx), fault_addr); + mono_runtime_printf_err ("Stack overflow in unmanaged: IP: %p, fault addr: %p", mono_arch_ip_from_context (ctx), fault_addr); if (!jit_tls->handling_stack_ovf) { jit_tls->restore_stack_prot = restore_stack_protection_tramp; jit_tls->handling_stack_ovf = 1; @@ -2098,7 +2107,6 @@ mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, } typedef struct { - FILE *stream; MonoMethod *omethod; int count; } PrintOverflowUserData; @@ -2108,7 +2116,6 @@ print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer da { MonoMethod *method = NULL; PrintOverflowUserData *user_data = data; - FILE *stream = user_data->stream; gchar *location; if (frame->ji) @@ -2126,11 +2133,11 @@ print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer da return FALSE; location = mono_debug_print_stack_frame (method, frame->native_offset, mono_domain_get ()); - fprintf (stream, " %s\n", location); + mono_runtime_printf_err (" %s", location); g_free (location); if (user_data->count == 1) { - fprintf (stream, " <...>\n"); + mono_runtime_printf_err (" <...>"); user_data->omethod = method; } else { user_data->omethod = NULL; @@ -2138,7 +2145,7 @@ print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer da user_data->count ++; } else - fprintf (stream, " at <0x%05x>\n", frame->native_offset); + mono_runtime_printf_err (" at <0x%05x>", frame->native_offset); return FALSE; } @@ -2150,41 +2157,39 @@ mono_handle_hard_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, MonoContext mctx; /* we don't do much now, but we can warn the user with a useful message */ - fprintf (stderr, "Stack overflow: IP: %p, fault addr: %p\n", mono_arch_ip_from_context (ctx), fault_addr); + mono_runtime_printf_err ("Stack overflow: IP: %p, fault addr: %p", mono_arch_ip_from_context (ctx), fault_addr); #ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX mono_arch_sigctx_to_monoctx (ctx, &mctx); - fprintf (stderr, "Stacktrace:\n"); + mono_runtime_printf_err ("Stacktrace:"); memset (&ud, 0, sizeof (ud)); - ud.stream = stderr; mono_walk_stack_with_ctx (print_overflow_stack_frame, &mctx, MONO_UNWIND_LOOKUP_ACTUAL_METHOD, &ud); #else if (ji && ji->method) - fprintf (stderr, "At %s\n", mono_method_full_name (ji->method, TRUE)); + mono_runtime_printf_err ("At %s", mono_method_full_name (ji->method, TRUE)); else - fprintf (stderr, "At .\n"); + mono_runtime_printf_err ("At ."); #endif _exit (1); } static gboolean -print_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer data) +print_stack_frame_to_stderr (StackFrameInfo *frame, MonoContext *ctx, gpointer data) { - FILE *stream = (FILE*)data; MonoMethod *method = NULL; if (frame->ji) method = frame->ji->method; if (method) { gchar *location = mono_debug_print_stack_frame (method, frame->native_offset, mono_domain_get ()); - fprintf (stream, " %s\n", location); + mono_runtime_printf_err (" %s", location); g_free (location); } else - fprintf (stream, " at <0x%05x>\n", frame->native_offset); + mono_runtime_printf_err (" at <0x%05x>", frame->native_offset); return FALSE; } @@ -2227,7 +2232,7 @@ mono_handle_native_sigsegv (int signal, void *ctx) return; if (mini_get_debug_options ()->suspend_on_sigsegv) { - fprintf (stderr, "Received SIGSEGV, suspending..."); + mono_runtime_printf_err ("Received SIGSEGV, suspending..."); while (1) ; } @@ -2237,11 +2242,9 @@ mono_handle_native_sigsegv (int signal, void *ctx) /* !jit_tls means the thread was not registered with the runtime */ if (jit_tls && mono_thread_internal_current ()) { - fprintf (stderr, "Stacktrace:\n\n"); - - mono_walk_stack (print_stack_frame, TRUE, stderr); + mono_runtime_printf_err ("Stacktrace:\n"); - fflush (stderr); + mono_walk_stack (print_stack_frame_to_stderr, TRUE, NULL); } #ifdef HAVE_BACKTRACE_SYMBOLS @@ -2251,17 +2254,15 @@ mono_handle_native_sigsegv (int signal, void *ctx) int i, size; const char *signal_str = (signal == SIGSEGV) ? "SIGSEGV" : "SIGABRT"; - fprintf (stderr, "\nNative stacktrace:\n\n"); + mono_runtime_printf_err ("\nNative stacktrace:\n"); size = backtrace (array, 256); names = backtrace_symbols (array, size); for (i =0; i < size; ++i) { - fprintf (stderr, "\t%s\n", names [i]); + mono_runtime_printf_err ("\t%s", names [i]); } free (names); - fflush (stderr); - /* Try to get more meaningful information using gdb */ #if !defined(HOST_WIN32) && defined(HAVE_SYS_SYSCALL_H) && defined(SYS_fork) @@ -2285,7 +2286,7 @@ mono_handle_native_sigsegv (int signal, void *ctx) exit (1); } - fprintf (stderr, "\nDebug info from gdb:\n\n"); + mono_runtime_printf_err ("\nDebug info from gdb:\n"); waitpid (pid, &status, 0); } #endif @@ -2294,14 +2295,14 @@ mono_handle_native_sigsegv (int signal, void *ctx) * on anything working. So try to print out lots of diagnostics, starting * with ones which have a greater chance of working. */ - fprintf (stderr, + mono_runtime_printf_err ( "\n" "=================================================================\n" "Got a %s while executing native code. This usually indicates\n" "a fatal error in the mono runtime or one of the native libraries \n" "used by your application.\n" - "=================================================================\n" - "\n", signal_str); + "=================================================================\n", + signal_str); } #endif @@ -2358,17 +2359,17 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx) mono_walk_stack_with_ctx (print_stack_frame_to_string, &ctx, MONO_UNWIND_LOOKUP_ALL, text); #else - printf ("\t\n"); + mono_runtime_printf ("\t"); #endif - fprintf (stdout, "%s", text->str); + mono_runtime_printf ("%s", text->str); #if PLATFORM_WIN32 && TARGET_WIN32 && _DEBUG OutputDebugStringA(text->str); #endif g_string_free (text, TRUE); - fflush (stdout); + mono_runtime_stdout_fflush (); } /* @@ -2658,12 +2659,15 @@ mono_invoke_unhandled_exception_hook (MonoObject *exc) MonoString *str = mono_object_to_string (exc, &other); if (str) { char *msg = mono_string_to_utf8 (str); - fprintf (stderr, "[ERROR] FATAL UNHANDLED EXCEPTION: %s\n", msg); - fflush (stderr); + mono_runtime_printf_err ("[ERROR] FATAL UNHANDLED EXCEPTION: %s", msg); g_free (msg); } +#if defined(__APPLE__) && defined(__arm__) + g_assertion_message ("Terminating runtime due to unhandled exception"); +#else exit (mono_environment_exitcode_get ()); +#endif } g_assert_not_reached (); diff --git a/mono/mini/mini-llvm-cpp.cpp b/mono/mini/mini-llvm-cpp.cpp index 42be2e03cb0..2b90cd692da 100644 --- a/mono/mini/mini-llvm-cpp.cpp +++ b/mono/mini/mini-llvm-cpp.cpp @@ -20,6 +20,14 @@ // possible // +#include "config.h" +//undef those as llvm defines them on its own config.h as well. +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + #include #include @@ -51,6 +59,10 @@ ((LLVM_MAJOR_VERSION > (major)) || \ ((LLVM_MAJOR_VERSION == (major)) && (LLVM_MINOR_VERSION >= (minor)))) +// extern "C" void LLVMInitializeARMTargetInfo(); +// extern "C" void LLVMInitializeARMTarget (); +// extern "C" void LLVMInitializeARMTargetMC (); + using namespace llvm; class MonoJITMemoryManager : public JITMemoryManager @@ -122,20 +134,16 @@ public: } virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) { - if (!strcmp (Name.c_str (), "__bzero")) { - return (void*)bzero; - } else { - void *res; - char *err; - - err = dlsym_cb (Name.c_str (), &res); - if (err) { - outs () << "Unable to resolve: " << Name << ": " << err << "\n"; - assert(0); - return NULL; - } - return res; + void *res; + char *err; + + err = dlsym_cb (Name.c_str (), &res); + if (err) { + outs () << "Unable to resolve: " << Name << ": " << err << "\n"; + assert(0); + return NULL; } + return res; } }; @@ -510,9 +518,15 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func force_pass_linking (); +#ifdef TARGET_ARM + LLVMInitializeARMTarget (); + LLVMInitializeARMTargetInfo (); + LLVMInitializeARMTargetMC (); +#else LLVMInitializeX86Target (); LLVMInitializeX86TargetInfo (); LLVMInitializeX86TargetMC (); +#endif mono_mm = new MonoJITMemoryManager (); mono_mm->alloc_cb = alloc_cb; diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index f97da754b40..33b697da5ec 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -1821,7 +1821,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef *args; LLVMCallInfo *cinfo; GSList *l; - int i, len; + int i, len, nargs; gboolean vretaddr; LLVMTypeRef llvm_sig; gpointer target; @@ -1943,23 +1943,27 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, /* * Collect and convert arguments */ - len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg); + nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg; + len = sizeof (LLVMValueRef) * nargs; args = alloca (len); memset (args, 0, len); l = call->out_ireg_args; if (call->rgctx_arg_reg) { g_assert (values [call->rgctx_arg_reg]); + g_assert (sinfo.rgctx_arg_pindex < nargs); args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg]; } if (call->imt_arg_reg) { g_assert (values [call->imt_arg_reg]); + g_assert (sinfo.imt_arg_pindex < nargs); args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg]; } if (vretaddr) { if (!addresses [call->inst.dreg]) addresses [call->inst.dreg] = build_alloca (ctx, sig->ret); + g_assert (sinfo.vret_arg_pindex < nargs); args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), ""); } @@ -4112,18 +4116,16 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) void mono_llvm_check_method_supported (MonoCompile *cfg) { - /* MonoMethodHeader *header = cfg->header; MonoExceptionClause *clause; int i; - */ if (cfg->method->save_lmf) { cfg->exception_message = g_strdup ("lmf"); cfg->disable_llvm = TRUE; } -#if 0 +#if 1 for (i = 0; i < header->num_clauses; ++i) { clause = &header->clauses [i]; @@ -4744,11 +4746,21 @@ static char* dlsym_cb (const char *name, void **symbol) { MonoDl *current; + char *err; - current = mono_dl_open (NULL, 0, NULL); - g_assert (current); + err = NULL; + if (!strcmp (name, "__bzero")) { + *symbol = (void*)bzero; + } else { + current = mono_dl_open (NULL, 0, NULL); + g_assert (current); - return mono_dl_symbol (current, name, symbol); + err = mono_dl_symbol (current, name, symbol); + } +#ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK + *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol)); +#endif + return err; } static inline void diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index f562ea7f5ad..75a6a7a24ad 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -3158,6 +3158,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) MonoCallInst *call = (MonoCallInst*)ins; int pos = 0, i; + ins->flags |= MONO_INST_GC_CALLSITE; + ins->backend.pc_offset = code - cfg->native_code; + /* FIXME: no tracing support... */ if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE) code = mono_arch_instrument_epilog (cfg, mono_profiler_method_leave, code, FALSE); @@ -5906,9 +5909,9 @@ mono_arch_get_patch_offset (guint8 *code) { if ((code [0] == 0x8b) && (x86_modrm_mod (code [1]) == 0x2)) return 2; - else if ((code [0] == 0xba)) + else if (code [0] == 0xba) return 1; - else if ((code [0] == 0x68)) + else if (code [0] == 0x68) /* push IMM */ return 1; else if ((code [0] == 0xff) && (x86_modrm_reg (code [1]) == 0x6)) diff --git a/mono/mini/mini.c b/mono/mini/mini.c index f52a44fa215..a80150fa634 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -5060,8 +5060,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool } /* collect statistics */ +#ifndef DISABLE_PERFCOUNTERS mono_perfcounters->jit_methods++; mono_perfcounters->jit_bytes += header->code_size; +#endif mono_jit_stats.allocated_code_size += cfg->code_len; code_size_ratio = cfg->code_len; if (code_size_ratio > mono_jit_stats.biggest_method_size && mono_jit_stats.enabled) { @@ -5290,7 +5292,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in if (mono_aot_only) { char *fullname = mono_method_full_name (method, TRUE); - char *msg = g_strdup_printf ("Attempting to JIT compile method '%s' while running with --aot-only.\n", fullname); + char *msg = g_strdup_printf ("Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname); *jit_ex = mono_get_exception_execution_engine (msg); g_free (fullname); @@ -5597,7 +5599,7 @@ static void invalidated_delegate_trampoline (char *desc) { g_error ("Unmanaged code called delegate of type %s which was already garbage collected.\n" - "See http://www.go-mono.com/delegate.html for an explanation and ways to fix this.", + "See http://www.mono-project.com/Diagnostic:Delegate for an explanation and ways to fix this.", desc); } #endif @@ -6473,7 +6475,6 @@ mini_init (const char *filename, const char *runtime_version) g_thread_init (NULL); mono_native_tls_alloc (&mono_jit_tls_id, NULL); - setup_jit_tls_data ((gpointer)-1, mono_thread_abort); if (default_opt & MONO_OPT_AOT) mono_aot_init (); @@ -6566,6 +6567,11 @@ mini_init (const char *filename, const char *runtime_version) mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers", mono_runtime_install_handlers); +#ifdef PLATFORM_ANDROID + mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal", + mono_debugger_agent_unhandled_exception); +#endif + mono_create_helper_signatures (); register_jit_stats (); diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 18b0050b625..459589df198 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -177,7 +177,8 @@ typedef enum { typedef enum { MONO_AOT_FILE_FLAG_WITH_LLVM = 1, MONO_AOT_FILE_FLAG_FULL_AOT = 2, - MONO_AOT_FILE_FLAG_DEBUG = 4 + MONO_AOT_FILE_FLAG_DEBUG = 4, + MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES = 8 } MonoAotFileFlags; /* This structure is stored in the AOT file */ @@ -203,6 +204,9 @@ typedef struct MonoAotFileInfo gpointer method_info_offsets; gpointer ex_info_offsets; gpointer code_offsets; +#ifdef MONOTOUCH + gpointer method_addresses; +#endif gpointer extra_method_info_offsets; gpointer extra_method_table; gpointer got_info_offsets; @@ -2078,6 +2082,7 @@ gpointer mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gpointer mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) MONO_INTERNAL; gpointer mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL; gpointer mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL; +guint8 *mono_arch_create_llvm_native_thunk (MonoDomain *domain, guint8* addr) MONO_LLVM_INTERNAL; GList *mono_arch_get_allocatable_int_vars (MonoCompile *cfg) MONO_INTERNAL; GList *mono_arch_get_global_int_regs (MonoCompile *cfg) MONO_INTERNAL; GList *mono_arch_get_global_fp_regs (MonoCompile *cfg) MONO_INTERNAL; diff --git a/mono/mini/trace.c b/mono/mini/trace.c index f8643d77cdf..d9a5b50e41f 100644 --- a/mono/mini/trace.c +++ b/mono/mini/trace.c @@ -24,6 +24,13 @@ #include #include "trace.h" +#if defined (PLATFORM_ANDROID) || (defined (TARGET_IOS) && defined (TARGET_IOS)) +# undef printf +# define printf(...) g_log("mono", G_LOG_LEVEL_MESSAGE, __VA_ARGS__) +# undef fprintf +# define fprintf(__ignore, ...) g_log ("mono-gc", G_LOG_LEVEL_MESSAGE, __VA_ARGS__) +#endif + static MonoTraceSpec trace_spec; gboolean diff --git a/mono/mini/tramp-amd64.c b/mono/mini/tramp-amd64.c index 3c108f307cf..ee2c8c410c0 100644 --- a/mono/mini/tramp-amd64.c +++ b/mono/mini/tramp-amd64.c @@ -233,6 +233,25 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr) #endif } +guint8* +mono_arch_create_llvm_native_thunk (MonoDomain *domain, guint8 *addr) +{ + /* + * The caller is LLVM code and the call displacement might exceed 32 bits. We can't determine the caller address, so + * we add a thunk every time. + * Since the caller is also allocated using the domain code manager, hopefully the displacement will fit into 32 bits. + * FIXME: Avoid this if possible if !MONO_ARCH_NOMAP32BIT and ADDR is 32 bits. + */ + guint8 *thunk_start, *thunk_code; + + thunk_start = thunk_code = mono_domain_code_reserve (mono_domain_get (), 32); + amd64_jump_membase (thunk_code, AMD64_RIP, 0); + *(guint64*)thunk_code = (guint64)addr; + addr = thunk_start; + mono_arch_flush_icache (thunk_start, thunk_code - thunk_start); + return addr; +} + void mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) { diff --git a/mono/mini/tramp-arm.c b/mono/mini/tramp-arm.c index 5711ef1f180..1aeeeffa6bd 100644 --- a/mono/mini/tramp-arm.c +++ b/mono/mini/tramp-arm.c @@ -740,8 +740,13 @@ mono_arch_get_call_target (guint8 *code) { guint32 ins = ((guint32*)(gpointer)code) [-1]; +#if MONOTOUCH + /* Should be a 'bl' or a 'b' */ + if (((ins >> 25) & 0x7) == 0x5) { +#else /* Should be a 'bl' */ if ((((ins >> 25) & 0x7) == 0x5) && (((ins >> 24) & 0x1) == 0x1)) { +#endif gint32 disp = ((gint32)ins) & 0xffffff; guint8 *target = code - 4 + 8 + (disp * 4); diff --git a/mono/mini/tramp-x86.c b/mono/mini/tramp-x86.c index 54079cb2003..09dc882e071 100644 --- a/mono/mini/tramp-x86.c +++ b/mono/mini/tramp-x86.c @@ -125,7 +125,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr) */ code -= 6; orig_code -= 6; - if ((code [1] == 0xe8)) { + if (code [1] == 0xe8) { if (can_write) { InterlockedExchange ((gint32*)(orig_code + 2), (guint)addr - ((guint)orig_code + 1) - 5); diff --git a/mono/monograph/Makefile.am b/mono/monograph/Makefile.am index d40e38b8470..64fe072e9a0 100644 --- a/mono/monograph/Makefile.am +++ b/mono/monograph/Makefile.am @@ -4,6 +4,9 @@ export HOST_CC endif if JIT_SUPPORTED +if DISABLE_EXECUTABLES +runtime_lib=../mini/$(LIBMONO_LA) $(static_libs) +else if !SHARED_MONO static_libs= \ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ @@ -16,11 +19,15 @@ runtime_lib=../mini/$(LIBMONO_LA) $(static_libs) else runtime_lib=../mini/$(LIBMONO_LA) endif +endif else runtime_lib=../interpreter/libmint.la endif +if DISABLE_LIBRARIES +else bin_PROGRAMS = monograph +endif AM_CPPFLAGS = \ -I$(top_srcdir) \ diff --git a/mono/profiler/Makefile.am b/mono/profiler/Makefile.am index 33dda5c3798..c69c8dbcae5 100644 --- a/mono/profiler/Makefile.am +++ b/mono/profiler/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(GLIB_CFLAGS) +if !DISABLE_LIBRARIES if !DISABLE_PROFILER if JIT_SUPPORTED bin_PROGRAMS = mprof-report @@ -18,12 +19,16 @@ libmono_profiler_log_la_LDFLAGS = -Wl,-undefined -Wl,suppress -Wl,-flat_namespac endif endif endif +endif if HAVE_OPROFILE # Do something that uses OPROFILE_CFLAGS and OPROFILE_LIBS endif if SUPPORT_BOEHM +if DISABLE_EXECUTABLES +LIBMONO=$(top_builddir)/mono/mini/$(LIBMONO_LA) +else if !SHARED_MONO static_libs= \ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ @@ -36,6 +41,7 @@ LIBMONO=$(top_builddir)/mono/mini/$(LIBMONO_LA) $(static_libs) else LIBMONO=$(top_builddir)/mono/mini/$(LIBMONO_LA) endif +endif else LIBMONO=$(top_builddir)/mono/mini/libmonosgen-$(API_VER).la endif diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index bfb9be06508..57e016c111e 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -791,33 +791,34 @@ test-type-load: TestDriver.dll @$(RUNTIME) load-exceptions.exe > load-exceptions.exe.stdout 2> load-exceptions.exe.stderr -EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs +EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs SGEN_TESTS = \ sgen-descriptors.exe \ - sgen-gshared-vtype.exe + sgen-gshared-vtype.exe \ + sgen-domain-unload.exe sgen-regular-tests: $(SGEN_TESTS) @for fn in $+ ; do \ echo "Testing $$fn ..."; \ - MONO_GC_PARAMS=major=marksweep-par MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=major=marksweep-par,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=major=marksweep,concurrent-sweep MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=minor=split,major=marksweep,concurrent-sweep MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=major=marksweep-par,minor=split,alloc-ratio=95 MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ - MONO_GC_PARAMS=minor=split,alloc-ratio=95 MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout 2> $$fn.stderr || exit 1; \ + MONO_GC_PARAMS=major=marksweep-par MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.1.stdout 2> $$fn.1.stderr || exit 1; \ + MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.2.stdout 2> $$fn.2.stderr || exit 1; \ + MONO_GC_PARAMS=major=marksweep-par,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.3.stdout 2> $$fn.3.stderr || exit 1; \ + MONO_GC_PARAMS=minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.4.stdout 2> $$fn.4.stderr || exit 1; \ + MONO_GC_PARAMS=major=marksweep,concurrent-sweep MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.5.stdout 2> $$fn.5.stderr || exit 1; \ + MONO_GC_PARAMS=minor=split,major=marksweep,concurrent-sweep MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.6.stdout 2> $$fn.6.stderr || exit 1; \ + MONO_GC_PARAMS=major=marksweep-par,minor=split,alloc-ratio=95 MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.7.stdout 2> $$fn.7.stderr || exit 1; \ + MONO_GC_PARAMS=minor=split,alloc-ratio=95 MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.8.stdout 2> $$fn.8.stderr || exit 1; \ done sgen-tests: sgen-regular-tests sgen-bridge.exe sgen-bridge-major-fragmentation.exe @echo "Testing sgen-bridge.exe ..."; \ - MONO_GC_PARAMS=bridge=Bridge MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge.exe > sgen-bridge.exe.stdout 2> sgen-bridge.exe.stderr || exit 1; \ - MONO_GC_PARAMS=bridge=Bridge,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge.exe > sgen-bridge.exe.stdout 2> sgen-bridge.exe.stderr || exit 1; \ + MONO_GC_PARAMS=bridge=Bridge MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge.exe > sgen-bridge.exe.1.stdout 2> sgen-bridge.exe.1.stderr || exit 1; \ + MONO_GC_PARAMS=bridge=Bridge,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge.exe > sgen-bridge.exe.2.stdout 2> sgen-bridge.exe.2.stderr || exit 1; \ echo "Testing sgen-bridge-major-fragmentation.exe ..."; \ - MONO_GC_PARAMS=bridge=Bridge MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge-major-fragmentation.exe > sgen-bridge-major-fragmentation.exe.stdout 2> sgen-bridge-major-fragmentation.exe.stderr || exit 1; \ - MONO_GC_PARAMS=bridge=Bridge,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge-major-fragmentation.exe > sgen-bridge-major-fragmentation.exe.stdout 2> sgen-bridge-major-fragmentation.exe.stderr || exit 1; + MONO_GC_PARAMS=bridge=Bridge MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge-major-fragmentation.exe > sgen-bridge-major-fragmentation.exe.1.stdout 2> sgen-bridge-major-fragmentation.exe.1.stderr || exit 1; \ + MONO_GC_PARAMS=bridge=Bridge,minor=split MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) sgen-bridge-major-fragmentation.exe > sgen-bridge-major-fragmentation.exe.2.stdout 2> sgen-bridge-major-fragmentation.exe.2.stderr || exit 1; # Generated tests for runtime invoke diff --git a/mono/tests/finalizer-exception.cs b/mono/tests/finalizer-exception.cs index d11e1696f14..1496dc54b47 100644 --- a/mono/tests/finalizer-exception.cs +++ b/mono/tests/finalizer-exception.cs @@ -6,13 +6,25 @@ public class FinalizerException { throw new Exception (); } + /* + * We allocate the exception object deep down the stack so + * that it doesn't get pinned. + */ + public static void MakeException (int depth) { + if (depth <= 0) { + new FinalizerException (); + return; + } + MakeException (depth - 1); + } + public static int Main () { AppDomain.CurrentDomain.UnhandledException += (sender, args) => { Console.WriteLine ("caught"); Environment.Exit (0); }; - new FinalizerException (); + MakeException (100); GC.Collect (); GC.WaitForPendingFinalizers (); diff --git a/mono/tests/sgen-domain-unload.cs b/mono/tests/sgen-domain-unload.cs new file mode 100644 index 00000000000..670f218b3fb --- /dev/null +++ b/mono/tests/sgen-domain-unload.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +public class Bar { + public object a, b, c; + +} +class Driver { + static void ProduceSimpleHeapWithLOS () { + Console.WriteLine ("running in {0}", AppDomain.CurrentDomain); + byte[] a = new byte [4 * 1000 * 1000]; + byte[] b = new byte [4 * 1000 * 1000]; + byte[] c = new byte [4 * 1000 * 1000]; + var lst = new List (); + + Bar la, lb, lc; + la = lb = lc = null; + for (int i = 0; i < 1000 * 200; ++i) { + var ba = new Bar (); + var bb = new Bar (); + var bc = new Bar (); + ba.a = la; + ba.b = bb; + ba.c = a; + + bb.a = bc; + ba.b = b; + bb.c = lb; + + bc.a = c; + bc.b = lc; + bc.c = ba; + + la = ba; + lb = bb; + lc = bc; + + lst.Add (ba); + } + + } + + static void SimpleHeapWithLOS () { + ProduceSimpleHeapWithLOS (); + } + + static void CrossDomainTest (string name, CrossAppDomainDelegate dele) { + Console.WriteLine ("----Testing {0}----", name); + for (int i = 0; i < 20; ++i) { + var ad = AppDomain.CreateDomain (string.Format ("domain-{0}-{1}", name, i)); + ad.DoCallBack (dele); + AppDomain.Unload (ad); + } + } + + static void Main () { + CrossDomainTest ("simple-heap-with-los", Driver.SimpleHeapWithLOS); + } +} \ No newline at end of file diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index 5e078dccfaa..2745782762e 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -103,6 +103,8 @@ monoutils_sources = \ arch_sources = +if !CROSS_COMPILE + if X86 arch_sources += mach-support-x86.c endif @@ -115,6 +117,12 @@ if ARM arch_sources += mach-support-arm.c endif +else + +arch_sources += mach-support-unknown.c + +endif + libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources) libmonoutilsincludedir = $(includedir)/mono-$(API_VER)/mono/utils diff --git a/mono/utils/lock-free-alloc.c b/mono/utils/lock-free-alloc.c index 4c95990ddee..c2058cc17ad 100644 --- a/mono/utils/lock-free-alloc.c +++ b/mono/utils/lock-free-alloc.c @@ -111,14 +111,14 @@ typedef struct _MonoLockFreeAllocDescriptor Descriptor; struct _MonoLockFreeAllocDescriptor { MonoLockFreeQueueNode node; MonoLockFreeAllocator *heap; - Anchor anchor; + volatile Anchor anchor; unsigned int slot_size; unsigned int max_count; gpointer sb; #ifndef DESC_AVAIL_DUMMY - Descriptor *next; + Descriptor * volatile next; #endif - gboolean in_use; + gboolean in_use; /* used for debugging only */ }; #define NUM_DESC_BATCH 64 diff --git a/mono/utils/lock-free-queue.h b/mono/utils/lock-free-queue.h index 7a494729ef3..32fec4cad3d 100644 --- a/mono/utils/lock-free-queue.h +++ b/mono/utils/lock-free-queue.h @@ -35,7 +35,7 @@ typedef struct _MonoLockFreeQueueNode MonoLockFreeQueueNode; struct _MonoLockFreeQueueNode { - MonoLockFreeQueueNode *next; + MonoLockFreeQueueNode * volatile next; #ifdef QUEUE_DEBUG gint32 in_queue; #endif @@ -43,16 +43,16 @@ struct _MonoLockFreeQueueNode { typedef struct { MonoLockFreeQueueNode node; - gint32 in_use; + volatile gint32 in_use; } MonoLockFreeQueueDummy; #define MONO_LOCK_FREE_QUEUE_NUM_DUMMIES 2 typedef struct { - volatile MonoLockFreeQueueNode *head; - volatile MonoLockFreeQueueNode *tail; + MonoLockFreeQueueNode * volatile head; + MonoLockFreeQueueNode * volatile tail; MonoLockFreeQueueDummy dummies [MONO_LOCK_FREE_QUEUE_NUM_DUMMIES]; - gint32 has_dummy; + volatile gint32 has_dummy; } MonoLockFreeQueue; void mono_lock_free_queue_init (MonoLockFreeQueue *q) MONO_INTERNAL; diff --git a/mono/utils/mach-support-amd64.c b/mono/utils/mach-support-amd64.c index ab59ed5cfdf..e889a522c49 100644 --- a/mono/utils/mach-support-amd64.c +++ b/mono/utils/mach-support-amd64.c @@ -39,7 +39,7 @@ mono_mach_arch_get_mcontext_size () } void -mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) { x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state; struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context; @@ -48,7 +48,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t contex } void -mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) +mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) { x86_thread_state64_t *arch_state = (x86_thread_state64_t *) state; struct __darwin_mcontext64 *ctx = (struct __darwin_mcontext64 *) context; diff --git a/mono/utils/mach-support-arm.c b/mono/utils/mach-support-arm.c index cca95abe2ac..bd1c79de855 100644 --- a/mono/utils/mach-support-arm.c +++ b/mono/utils/mach-support-arm.c @@ -41,7 +41,7 @@ mono_mach_arch_get_mcontext_size () } void -mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) { arm_thread_state_t *arch_state = (arm_thread_state_t *) state; struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context; @@ -50,7 +50,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t contex } void -mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) +mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) { arm_thread_state_t *arch_state = (arm_thread_state_t *) state; struct __darwin_mcontext *ctx = (struct __darwin_mcontext *) context; @@ -72,7 +72,7 @@ mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mac *count = ARM_THREAD_STATE_COUNT; - ret = thread_get_state (thread, ARM_THREAD_STATE_COUNT, (thread_state_t) arch_state, count); + ret = thread_get_state (thread, ARM_THREAD_STATE, (thread_state_t) arch_state, count); return ret; } diff --git a/mono/utils/mach-support-unknown.c b/mono/utils/mach-support-unknown.c new file mode 100644 index 00000000000..fbba8dc882e --- /dev/null +++ b/mono/utils/mach-support-unknown.c @@ -0,0 +1,73 @@ +/* + * mach-support-unknown.c: mach support for cross compilers (IOW, none) + * + * Authors: + * Rodrigo Kumpera (kumpera@gmail.com) + * + * (C) 2012 Xamarin, Inc. + */ + +#include + +#if defined(__MACH__) +#include +#include +#include +#include "utils/mono-sigcontext.h" +#include "mach-support.h" + +void * +mono_mach_arch_get_ip (thread_state_t state) +{ + g_assert_not_reached (); +} + +void * +mono_mach_arch_get_sp (thread_state_t state) +{ + g_assert_not_reached (); +} + +int +mono_mach_arch_get_mcontext_size () +{ + g_assert_not_reached (); +} + +void +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) +{ + g_assert_not_reached (); +} + +void +mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) +{ + g_assert_not_reached (); +} + + +int +mono_mach_arch_get_thread_state_size () +{ + g_assert_not_reached (); +} + +kern_return_t +mono_mach_arch_get_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t *count) +{ + g_assert_not_reached (); +} + +kern_return_t +mono_mach_arch_set_thread_state (thread_port_t thread, thread_state_t state, mach_msg_type_number_t count) +{ + g_assert_not_reached (); +} + +void * +mono_mach_arch_get_tls_value_from_thread (pthread_t thread, guint32 key) +{ + g_assert_not_reached (); +} +#endif diff --git a/mono/utils/mach-support-x86.c b/mono/utils/mach-support-x86.c index d3c967d2ed8..e65fe6bdeef 100644 --- a/mono/utils/mach-support-x86.c +++ b/mono/utils/mach-support-x86.c @@ -39,7 +39,7 @@ mono_mach_arch_get_mcontext_size () } void -mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) +mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) { x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state; struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context; @@ -48,7 +48,7 @@ mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t contex } void -mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) +mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) { x86_thread_state32_t *arch_state = (x86_thread_state32_t *) state; struct __darwin_mcontext32 *ctx = (struct __darwin_mcontext32 *) context; diff --git a/mono/utils/mach-support.h b/mono/utils/mach-support.h index 06b34e8689b..ffed22f53c9 100644 --- a/mono/utils/mach-support.h +++ b/mono/utils/mach-support.h @@ -25,8 +25,8 @@ void *mono_mach_arch_get_ip (thread_state_t state) MONO_INTERNAL; void *mono_mach_arch_get_sp (thread_state_t state) MONO_INTERNAL; int mono_mach_arch_get_mcontext_size (void) MONO_INTERNAL; -void mono_mach_arch_thread_state_to_mcontext (thread_state_t state, mcontext_t context) MONO_INTERNAL; -void mono_mach_arch_mcontext_to_thread_state (mcontext_t context, thread_state_t state) MONO_INTERNAL; +void mono_mach_arch_thread_state_to_mcontext (thread_state_t state, void *context) MONO_INTERNAL; +void mono_mach_arch_mcontext_to_thread_state (void *context, thread_state_t state) MONO_INTERNAL; int mono_mach_arch_get_thread_state_size (void) MONO_INTERNAL; kern_return_t mono_mach_get_threads (thread_act_array_t *threads, guint32 *count) MONO_INTERNAL; diff --git a/mono/utils/memcheck.h b/mono/utils/memcheck.h index c89e3a2e178..fcc76446d9c 100644 --- a/mono/utils/memcheck.h +++ b/mono/utils/memcheck.h @@ -1,4 +1,4 @@ - + /* ---------------------------------------------------------------- @@ -13,7 +13,7 @@ This file is part of MemCheck, a heavyweight Valgrind tool for detecting memory errors. - Copyright (C) 2000-2009 Julian Seward. All rights reserved. + Copyright (C) 2000-2012 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -60,7 +60,6 @@ #ifndef __MEMCHECK_H #define __MEMCHECK_H -#ifdef __GNUC__ /* This file is for inclusion into client (your!) code. @@ -108,66 +107,48 @@ typedef /* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ VG_USERREQ__MAKE_MEM_NOACCESS, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Similarly, mark memory at _qzz_addr as addressable but undefined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ VG_USERREQ__MAKE_MEM_UNDEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Similarly, mark memory at _qzz_addr as addressable and defined for _qzz_len bytes. */ #define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is not altered: bytes which are addressable are marked as defined, but those which are not addressable are left unchanged. */ -#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ +#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Create a block-description handle. The description is an ascii string which is included in any messages pertaining to addresses within the specified memory range. Has no other effect on the properties of the memory range. */ -#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__CREATE_BLOCK, \ - _qzz_addr, _qzz_len, _qzz_desc, \ - 0, 0); \ - _qzz_res; \ - })) +#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CREATE_BLOCK, \ + (_qzz_addr), (_qzz_len), (_qzz_desc), \ + 0, 0) /* Discard a block-description-handle. Returns 1 for an invalid handle, 0 for a valid handle. */ #define VALGRIND_DISCARD(_qzz_blkindex) \ - (__extension__ ({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ VG_USERREQ__DISCARD, \ - 0, _qzz_blkindex, 0, 0, 0); \ - _qzz_res; \ - })) + 0, (_qzz_blkindex), 0, 0, 0) /* Client-code macros to check the state of memory. */ @@ -176,25 +157,19 @@ typedef If suitable addressibility is not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ -#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) +#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE, \ + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Check that memory at _qzz_addr is addressable and defined for _qzz_len bytes. If suitable addressibility and definedness are not established, Valgrind prints an error message and returns the address of the first offending byte. Otherwise it returns zero. */ #define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ VG_USERREQ__CHECK_MEM_IS_DEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) + (_qzz_addr), (_qzz_len), 0, 0, 0) /* Use this macro to force the definedness and addressibility of an lvalue to be checked. If suitable addressibility and definedness @@ -209,19 +184,27 @@ typedef /* Do a full memory leak check (like --leak-check=full) mid-execution. */ #define VALGRIND_DO_LEAK_CHECK \ - {unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DO_LEAK_CHECK, \ - 0, 0, 0, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \ + 0, 0, 0, 0, 0) + +/* Same as VALGRIND_DO_LEAK_CHECK but only showing the entries for + which there was an increase in leaked bytes or leaked nr of blocks + since the previous leak search. */ +#define VALGRIND_DO_ADDED_LEAK_CHECK \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \ + 0, 1, 0, 0, 0) + +/* Same as VALGRIND_DO_ADDED_LEAK_CHECK but showing entries with + increased or decreased leaked bytes/blocks since previous leak + search. */ +#define VALGRIND_DO_CHANGED_LEAK_CHECK \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \ + 0, 2, 0, 0, 0) /* Do a summary memory leak check (like --leak-check=summary) mid-execution. */ -#define VALGRIND_DO_QUICK_LEAK_CHECK \ - {unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DO_LEAK_CHECK, \ - 1, 0, 0, 0, 0); \ - } +#define VALGRIND_DO_QUICK_LEAK_CHECK \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \ + 1, 0, 0, 0, 0) /* Return number of leaked, dubious, reachable and suppressed bytes found by all previous leak checks. They must be lvalues. */ @@ -232,10 +215,10 @@ typedef are. We also initialise '_qzz_leaked', etc because VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as defined. */ \ - {unsigned long _qzz_res; \ + { \ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VALGRIND_DO_CLIENT_REQUEST_STMT( \ VG_USERREQ__COUNT_LEAKS, \ &_qzz_leaked, &_qzz_dubious, \ &_qzz_reachable, &_qzz_suppressed, 0); \ @@ -254,10 +237,10 @@ typedef are. We also initialise '_qzz_leaked', etc because VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as defined. */ \ - {unsigned long _qzz_res; \ + { \ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + VALGRIND_DO_CLIENT_REQUEST_STMT( \ VG_USERREQ__COUNT_LEAK_BLOCKS, \ &_qzz_leaked, &_qzz_dubious, \ &_qzz_reachable, &_qzz_suppressed, 0); \ @@ -277,15 +260,12 @@ typedef The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ -#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \ - (__extension__({unsigned long _qzz_res; \ - char* czza = (char*)zza; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__GET_VBITS, \ - czza, czzvbits, zznbytes, 0, 0 ); \ - _qzz_res; \ - })) +#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__GET_VBITS, \ + (const char*)(zza), \ + (char*)(zzvbits), \ + (zznbytes), 0, 0) /* Set the validity data for addresses [zza..zza+zznbytes-1], copying it from the provided zzvbits array. Return values: @@ -296,22 +276,12 @@ typedef The metadata is not copied in cases 0, 2 or 3 so it should be impossible to segfault your system by using this call. */ -#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \ - (__extension__({unsigned int _qzz_res; \ - char* czza = (char*)zza; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__SET_VBITS, \ - czza, czzvbits, zznbytes, 0, 0 ); \ - _qzz_res; \ - })) - -#else /* __GNUC__ */ - -#define RUNNING_ON_VALGRIND 0 -#define VALGRIND_DISCARD_TRANSLATIONS(x,y) do { } while (0) - -#endif /* __GNUC__ */ +#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__SET_VBITS, \ + (const char*)(zza), \ + (const char*)(zzvbits), \ + (zznbytes), 0, 0 ) #endif diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c index ef33f23bd95..81e2fe69b35 100644 --- a/mono/utils/mono-context.c +++ b/mono/utils/mono-context.c @@ -245,6 +245,7 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx) #include #include +#include void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) diff --git a/mono/utils/mono-context.h b/mono/utils/mono-context.h index 98ae7951d04..1cd7f55e31e 100644 --- a/mono/utils/mono-context.h +++ b/mono/utils/mono-context.h @@ -234,11 +234,28 @@ typedef struct { #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ARMREG_FP])) #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->regs [ARMREG_SP])) -// FIXME: #define MONO_CONTEXT_GET_CURRENT(ctx) do { \ - g_assert_not_reached (); \ + __asm__ __volatile__( \ + "push {r0}\n" \ + "push {r1}\n" \ + "mov r1, r0\n" \ + "mov r0, %0\n" \ + "str r1, [r0]!\n" \ + "pop {r1}\n" \ + "str r1, [r0]!\n" \ + "stmia r0!, {r2-r12}\n" \ + "str sp, [r0]!\n" \ + "str lr, [r0]!\n" \ + "str pc, [r0]!\n" \ + "pop {r0}\n" \ + : \ + : "r" (&ctx.regs) \ + : "memory" \ + ); \ + ctx.pc = ctx.regs [15]; \ } while (0) + #elif defined(__mono_ppc__) /* defined(__arm__) */ /* we define our own structure and we'll copy the data diff --git a/mono/utils/mono-dl.c b/mono/utils/mono-dl.c index 2b9d518f4b0..dd29b526759 100644 --- a/mono/utils/mono-dl.c +++ b/mono/utils/mono-dl.c @@ -57,7 +57,12 @@ static const char suffixes [][4] = { #endif /* RTLD_LAZY */ #define SO_HANDLE_TYPE void* -#define LL_SO_OPEN(file,flags) dlopen ((file), (flags)) +#ifdef PLATFORM_ANDROID +/* Bionic doesn't support NULL filenames */ +# define LL_SO_OPEN(file,flags) ((file) ? dlopen ((file), (flags)) : NULL) +#else +# define LL_SO_OPEN(file,flags) dlopen ((file), (flags)) +#endif #define LL_SO_CLOSE(module) dlclose ((module)->handle) #define LL_SO_SYMBOL(module, name) dlsym ((module)->handle, (name)) #define LL_SO_TRFLAGS(flags) convert_flags ((flags)) diff --git a/mono/utils/mono-logger-internal.h b/mono/utils/mono-logger-internal.h index 10bcf17533b..1b50682e43b 100644 --- a/mono/utils/mono-logger-internal.h +++ b/mono/utils/mono-logger-internal.h @@ -91,6 +91,27 @@ mono_trace_message(MonoTraceMask mask, const char *format, ...) #endif /* !__GNUC__ */ +#if defined (PLATFORM_ANDROID) || (defined (TARGET_IOS) && defined (TARGET_IOS)) + +#define mono_gc_printf(gc_log_file, format, ...) g_log ("mono-gc", G_LOG_LEVEL_MESSAGE, format "\n", ##__VA_ARGS__) +#define mono_runtime_printf(format, ...) g_log ("mono-rt", G_LOG_LEVEL_MESSAGE, format "\n", ##__VA_ARGS__) +#define mono_runtime_printf_err(format, ...) g_log ("mono-rt", G_LOG_LEVEL_ERROR, format "\n", ##__VA_ARGS__) +#define mono_runtime_stdout_fflush() do { } while (0) + +#else + +#define mono_gc_printf(gc_log_file, format, ...) do { \ + fprintf (gc_log_file, format "\n", ##__VA_ARGS__); \ + fflush (gc_log_file); \ +} while (0) + +#define mono_runtime_printf(format, ...) fprintf (stdout, format "\n", ##__VA_ARGS__) +#define mono_runtime_printf_err(format, ...) fprintf (stderr, format "\n", ##__VA_ARGS__) +#define mono_runtime_stdout_fflush() do { fflush (stdout); } while (0) + +#endif + + G_END_DECLS #endif /* __MONO_LOGGER_INTERNAL_H__ */ diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h index 8b0634e7257..03247cf02a6 100644 --- a/mono/utils/mono-sigcontext.h +++ b/mono/utils/mono-sigcontext.h @@ -14,7 +14,7 @@ #include #endif -#if defined(__i386__) +#if defined(TARGET_X86) #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) #include @@ -34,7 +34,7 @@ #define UCONTEXT_REG_EDI(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_edi) #define UCONTEXT_REG_EIP(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_eip) #elif defined(__APPLE__) -# if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +# if defined (TARGET_IOS) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) #define UCONTEXT_REG_EAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__eax) #define UCONTEXT_REG_EBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__ebx) #define UCONTEXT_REG_ECX(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__ecx) @@ -152,7 +152,7 @@ typedef struct ucontext { #define UCONTEXT_REG_EIP(ctx) (((ucontext_t*)(ctx))->uc_mcontext.gregs [REG_EIP]) #endif -#elif defined(__x86_64__) +#elif defined(TARGET_AMD64) #if defined(__FreeBSD__) #include @@ -301,7 +301,7 @@ typedef struct ucontext { #define UCONTEXT_REG_LNK(ctx) ((ctx)->uc_mcontext.mc_lr) #endif -#elif defined(__arm__) +#elif defined(TARGET_ARM) #if defined(__APPLE__) typedef ucontext_t arm_ucontext; diff --git a/mono/utils/valgrind.h b/mono/utils/valgrind.h index a967f9dfc0d..315da5b0fc8 100644 --- a/mono/utils/valgrind.h +++ b/mono/utils/valgrind.h @@ -12,7 +12,7 @@ This file is part of Valgrind, a dynamic binary instrumentation framework. - Copyright (C) 2000-2009 Julian Seward. All rights reserved. + Copyright (C) 2000-2012 Julian Seward. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -73,7 +73,24 @@ #ifndef __VALGRIND_H #define __VALGRIND_H -#ifdef __GNUC__ + +/* ------------------------------------------------------------------ */ +/* VERSION NUMBER OF VALGRIND */ +/* ------------------------------------------------------------------ */ + +/* Specify Valgrind's version number, so that user code can + conditionally compile based on our version number. Note that these + were introduced at version 3.6 and so do not exist in version 3.5 + or earlier. The recommended way to use them to check for "version + X.Y or later" is (eg) + +#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ + && (__VALGRIND_MAJOR__ > 3 \ + || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) +*/ +#define __VALGRIND_MAJOR__ 3 +#define __VALGRIND_MINOR__ 8 + #include @@ -86,31 +103,44 @@ identifying architectures, which are different to the ones we use within the rest of Valgrind. Note, __powerpc__ is active for both 32 and 64-bit PPC, whereas __powerpc64__ is only active for the - latter (on Linux, that is). */ + latter (on Linux, that is). + + Misc note: how to find out what's predefined in gcc by default: + gcc -Wp,-dM somefile.c +*/ +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_win32 #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux -#undef PLAT_ppc32_aix5 -#undef PLAT_ppc64_aix5 +#undef PLAT_arm_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux -#if defined(_AIX) && defined(__64BIT__) -# define PLAT_ppc64_aix5 1 -#elif defined(_AIX) && !defined(__64BIT__) -# define PLAT_ppc32_aix5 1 -#elif defined(__APPLE__) && defined(__i386__) +#if defined(__APPLE__) && defined(__i386__) # define PLAT_x86_darwin 1 #elif defined(__APPLE__) && defined(__x86_64__) # define PLAT_amd64_darwin 1 -#elif defined(__i386__) +#elif defined(__MINGW32__) || defined(__CYGWIN32__) \ + || (defined(_WIN32) && defined(_M_IX86)) +# define PLAT_x86_win32 1 +#elif defined(__linux__) && defined(__i386__) # define PLAT_x86_linux 1 -#elif defined(__x86_64__) +#elif defined(__linux__) && defined(__x86_64__) # define PLAT_amd64_linux 1 -#elif defined(__powerpc__) && !defined(__powerpc64__) +#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) # define PLAT_ppc32_linux 1 -#elif defined(__powerpc__) && defined(__powerpc64__) +#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) # define PLAT_ppc64_linux 1 +#elif defined(__linux__) && defined(__arm__) +# define PLAT_arm_linux 1 +#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) +# define PLAT_s390x_linux 1 +#elif defined(__linux__) && defined(__mips__) +# define PLAT_mips32_linux 1 #else /* If we're not compiling for our target platform, don't generate any inline asms. */ @@ -125,17 +155,41 @@ /* in here of use to end-users -- skip to the next section. */ /* ------------------------------------------------------------------ */ +/* + * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client + * request. Accepts both pointers and integers as arguments. + * + * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind + * client request that does not return a value. + + * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind + * client request and whose value equals the client request result. Accepts + * both pointers and integers as arguments. Note that such calls are not + * necessarily pure functions -- they may have side effects. + */ + +#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ + _zzq_request, _zzq_arg1, _zzq_arg2, \ + _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + +#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ + _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ + (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) + #if defined(NVALGRIND) /* Define NVALGRIND to completely remove the Valgrind magic sequence from the compiled code (analogous to NDEBUG's effects on assert()) */ -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { \ - (_zzq_rlval) = (_zzq_default); \ - } + (_zzq_default) #else /* ! NVALGRIND */ @@ -176,7 +230,8 @@ /* ------------------------- x86-{linux,darwin} ---------------- */ -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) +#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ + || (defined(PLAT_x86_win32) && defined(__GNUC__)) typedef struct { @@ -188,10 +243,11 @@ typedef "roll $3, %%edi ; roll $13, %%edi\n\t" \ "roll $29, %%edi ; roll $19, %%edi\n\t" -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned int _zzq_args[6]; \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ volatile unsigned int _zzq_result; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ @@ -206,8 +262,8 @@ typedef : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ - _zzq_rlval = _zzq_result; \ - } + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ @@ -226,7 +282,89 @@ typedef __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%EAX */ \ "xchgl %%edx,%%edx\n\t" -#endif /* PLAT_x86_linux || PLAT_x86_darwin */ + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgl %%edi,%%edi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + +#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ + +/* ------------------------- x86-Win32 ------------------------- */ + +#if defined(PLAT_x86_win32) && !defined(__GNUC__) + +typedef + struct { + unsigned int nraddr; /* where's the code? */ + } + OrigFn; + +#if defined(_MSC_VER) + +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm rol edi, 3 __asm rol edi, 13 \ + __asm rol edi, 29 __asm rol edi, 19 + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ + (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ + (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ + (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) + +static __inline uintptr_t +valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, + uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, + uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, + uintptr_t _zzq_arg5) +{ + volatile uintptr_t _zzq_args[6]; + volatile unsigned int _zzq_result; + _zzq_args[0] = (uintptr_t)(_zzq_request); + _zzq_args[1] = (uintptr_t)(_zzq_arg1); + _zzq_args[2] = (uintptr_t)(_zzq_arg2); + _zzq_args[3] = (uintptr_t)(_zzq_arg3); + _zzq_args[4] = (uintptr_t)(_zzq_arg4); + _zzq_args[5] = (uintptr_t)(_zzq_arg5); + __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default + __SPECIAL_INSTRUCTION_PREAMBLE + /* %EDX = client_request ( %EAX ) */ + __asm xchg ebx,ebx + __asm mov _zzq_result, edx + } + return _zzq_result; +} + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned int __addr; \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + /* %EAX = guest_NRADDR */ \ + __asm xchg ecx,ecx \ + __asm mov __addr, eax \ + } \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_EAX ERROR + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ + __asm xchg edi,edi \ + } \ + } while (0) + +#else +#error Unsupported compiler. +#endif + +#endif /* PLAT_x86_win32 */ /* ------------------------ amd64-{linux,darwin} --------------- */ @@ -242,10 +380,11 @@ typedef "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned long long int _zzq_args[6]; \ + __extension__ \ + ({ volatile unsigned long long int _zzq_args[6]; \ volatile unsigned long long int _zzq_result; \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ @@ -260,8 +399,8 @@ typedef : "a" (&_zzq_args[0]), "0" (_zzq_default) \ : "cc", "memory" \ ); \ - _zzq_rlval = _zzq_result; \ - } + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ @@ -280,6 +419,15 @@ typedef __SPECIAL_INSTRUCTION_PREAMBLE \ /* call-noredir *%RAX */ \ "xchgq %%rdx,%%rdx\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "xchgq %%rdi,%%rdi\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) + #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ /* ------------------------ ppc32-linux ------------------------ */ @@ -296,11 +444,12 @@ typedef "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ - { unsigned int _zzq_args[6]; \ + __extension__ \ + ({ unsigned int _zzq_args[6]; \ unsigned int _zzq_result; \ unsigned int* _zzq_ptr; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ @@ -319,8 +468,8 @@ typedef : "=b" (_zzq_result) \ : "b" (_zzq_default), "b" (_zzq_ptr) \ : "cc", "memory", "r3", "r4"); \ - _zzq_rlval = _zzq_result; \ - } + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ @@ -340,6 +489,14 @@ typedef __SPECIAL_INSTRUCTION_PREAMBLE \ /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + #endif /* PLAT_ppc32_linux */ /* ------------------------ ppc64-linux ------------------------ */ @@ -357,13 +514,14 @@ typedef "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ "rotldi 0,0,61 ; rotldi 0,0,51\n\t" -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ - { unsigned long long int _zzq_args[6]; \ - register unsigned long long int _zzq_result __asm__("r3"); \ - register unsigned long long int* _zzq_ptr __asm__("r4"); \ + __extension__ \ + ({ unsigned long long int _zzq_args[6]; \ + unsigned long long int _zzq_result; \ + unsigned long long int* _zzq_ptr; \ _zzq_args[0] = (unsigned long long int)(_zzq_request); \ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ @@ -371,32 +529,37 @@ typedef _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ _zzq_ptr = _zzq_args; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __asm__ volatile("mr 3,%1\n\t" /*default*/ \ + "mr 4,%2\n\t" /*ptr*/ \ + __SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1" \ - : "=r" (_zzq_result) \ - : "0" (_zzq_default), "r" (_zzq_ptr) \ - : "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } + "or 1,1,1\n\t" \ + "mr %0,3" /*result*/ \ + : "=b" (_zzq_result) \ + : "b" (_zzq_default), "b" (_zzq_ptr) \ + : "cc", "memory", "r3", "r4"); \ + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr __asm__("r3"); \ + unsigned long long int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR */ \ - "or 2,2,2" \ - : "=r" (__addr) \ + "or 2,2,2\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ : \ - : "cc", "memory" \ + : "cc", "memory", "r3" \ ); \ _zzq_orig->nraddr = __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4" \ - : "=r" (__addr) \ + "or 4,4,4\n\t" \ + "mr %0,3" \ + : "=b" (__addr) \ : \ - : "cc", "memory" \ + : "cc", "memory", "r3" \ ); \ _zzq_orig->r2 = __addr; \ } @@ -406,151 +569,232 @@ typedef /* branch-and-link-to-noredir *%R11 */ \ "or 3,3,3\n\t" +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or 5,5,5\n\t" \ + ); \ + } while (0) + #endif /* PLAT_ppc64_linux */ -/* ------------------------ ppc32-aix5 ------------------------- */ +/* ------------------------- arm-linux ------------------------- */ -#if defined(PLAT_ppc32_aix5) +#if defined(PLAT_arm_linux) typedef struct { unsigned int nraddr; /* where's the code? */ - unsigned int r2; /* what tocptr do we need? */ } OrigFn; #define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ - "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" + "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ + "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ \ - { unsigned int _zzq_args[7]; \ - register unsigned int _zzq_result; \ - register unsigned int* _zzq_ptr; \ + __extension__ \ + ({volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ _zzq_args[0] = (unsigned int)(_zzq_request); \ _zzq_args[1] = (unsigned int)(_zzq_arg1); \ _zzq_args[2] = (unsigned int)(_zzq_arg2); \ _zzq_args[3] = (unsigned int)(_zzq_arg3); \ _zzq_args[4] = (unsigned int)(_zzq_arg4); \ _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "lwz 3, 24(4)\n\t" \ + __asm__ volatile("mov r3, %1\n\t" /*default*/ \ + "mov r4, %2\n\t" /*ptr*/ \ __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } + /* R3 = client_request ( R4 ) */ \ + "orr r10, r10, r10\n\t" \ + "mov %0, r3" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "cc","memory", "r3", "r4"); \ + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned int __addr; \ + unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ + /* R3 = guest_NRADDR */ \ + "orr r11, r11, r11\n\t" \ + "mov %0, r3" \ + : "=r" (__addr) \ : \ - : "r3", "cc", "memory" \ + : "cc", "memory", "r3" \ ); \ _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ } -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ +#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" + /* branch-and-link-to-noredir *%R4 */ \ + "orr r12, r12, r12\n\t" -#endif /* PLAT_ppc32_aix5 */ +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "orr r9, r9, r9\n\t" \ + : : : "cc", "memory" \ + ); \ + } while (0) -/* ------------------------ ppc64-aix5 ------------------------- */ +#endif /* PLAT_arm_linux */ -#if defined(PLAT_ppc64_aix5) +/* ------------------------ s390x-linux ------------------------ */ + +#if defined(PLAT_s390x_linux) + +typedef + struct { + unsigned long long int nraddr; /* where's the code? */ + } + OrigFn; + +/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific + * code. This detection is implemented in platform specific toIR.c + * (e.g. VEX/priv/guest_s390_decoder.c). + */ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "lr 15,15\n\t" \ + "lr 1,1\n\t" \ + "lr 2,2\n\t" \ + "lr 3,3\n\t" + +#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" +#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" +#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" +#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({volatile unsigned long long int _zzq_args[6]; \ + volatile unsigned long long int _zzq_result; \ + _zzq_args[0] = (unsigned long long int)(_zzq_request); \ + _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ + __asm__ volatile(/* r2 = args */ \ + "lgr 2,%1\n\t" \ + /* r3 = default */ \ + "lgr 3,%2\n\t" \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CLIENT_REQUEST_CODE \ + /* results = r3 */ \ + "lgr %0, 3\n\t" \ + : "=d" (_zzq_result) \ + : "a" (&_zzq_args[0]), "0" (_zzq_default) \ + : "cc", "2", "3", "memory" \ + ); \ + _zzq_result; \ + }) + +#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ + { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ + volatile unsigned long long int __addr; \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __GET_NR_CONTEXT_CODE \ + "lgr %0, 3\n\t" \ + : "=a" (__addr) \ + : \ + : "cc", "3", "memory" \ + ); \ + _zzq_orig->nraddr = __addr; \ + } + +#define VALGRIND_CALL_NOREDIR_R1 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + __CALL_NO_REDIR_CODE + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + __VEX_INJECT_IR_CODE); \ + } while (0) + +#endif /* PLAT_s390x_linux */ + +/* ------------------------- mips32-linux ---------------- */ + +#if defined(PLAT_mips32_linux) typedef struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ + unsigned int nraddr; /* where's the code? */ } OrigFn; -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned long long int _zzq_args[7]; \ - register unsigned long long int _zzq_result; \ - register unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int long long)(_zzq_request); \ - _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int long long)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "ld 3, 48(4)\n\t" \ +/* .word 0x342 + * .word 0x742 + * .word 0xC2 + * .word 0x4C2*/ +#define __SPECIAL_INSTRUCTION_PREAMBLE \ + "srl $0, $0, 13\n\t" \ + "srl $0, $0, 29\n\t" \ + "srl $0, $0, 3\n\t" \ + "srl $0, $0, 19\n\t" + +#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + _zzq_default, _zzq_request, \ + _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ + __extension__ \ + ({ volatile unsigned int _zzq_args[6]; \ + volatile unsigned int _zzq_result; \ + _zzq_args[0] = (unsigned int)(_zzq_request); \ + _zzq_args[1] = (unsigned int)(_zzq_arg1); \ + _zzq_args[2] = (unsigned int)(_zzq_arg2); \ + _zzq_args[3] = (unsigned int)(_zzq_arg3); \ + _zzq_args[4] = (unsigned int)(_zzq_arg4); \ + _zzq_args[5] = (unsigned int)(_zzq_arg5); \ + __asm__ volatile("move $11, %1\n\t" /*default*/ \ + "move $12, %2\n\t" /*ptr*/ \ __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } + /* T3 = client_request ( T4 ) */ \ + "or $13, $13, $13\n\t" \ + "move %0, $11\n\t" /*result*/ \ + : "=r" (_zzq_result) \ + : "r" (_zzq_default), "r" (&_zzq_args[0]) \ + : "cc","memory", "t3", "t4"); \ + _zzq_result; \ + }) #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr; \ + volatile unsigned int __addr; \ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ + /* %t9 = guest_NRADDR */ \ + "or $14, $14, $14\n\t" \ + "move %0, $11" /*result*/ \ + : "=r" (__addr) \ : \ - : "r3", "cc", "memory" \ + : "cc", "memory" , "t3" \ ); \ _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ } -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" +#define VALGRIND_CALL_NOREDIR_T9 \ + __SPECIAL_INSTRUCTION_PREAMBLE \ + /* call-noredir *%t9 */ \ + "or $15, $15, $15\n\t" + +#define VALGRIND_VEX_INJECT_IR() \ + do { \ + __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ + "or $11, $11, $11\n\t" \ + ); \ + } while (0) -#endif /* PLAT_ppc64_aix5 */ + +#endif /* PLAT_mips32_linux */ /* Insert assembly code for other platforms here... */ @@ -581,17 +825,20 @@ typedef */ /* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ + VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts + the default behaviour equivalance class tag "0000" into the name. + See pub_tool_redir.h for details -- normally you don't need to + think about this, though. */ /* Use an extra level of macroisation so as to ensure the soname/fnname args are fully macro-expanded before pasting them together. */ #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgwZU_,soname,_,fnname) + VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgwZZ_,soname,_,fnname) + VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) /* Use this macro from within a wrapper function to collect the context (address and possibly other info) of the original function. @@ -599,6 +846,18 @@ typedef macros. The type of the argument _lval is OrigFn. */ #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) +/* Also provide end-user facilities for function replacement, rather + than wrapping. A replacement function differs from a wrapper in + that it has no way to get hold of the original function being + called, and hence no way to call onwards to it. In a replacement + function, VALGRIND_GET_ORIG_FN always returns zero. */ + +#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ + VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) + +#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ + VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) + /* Derivatives of the main macros below, for calling functions returning void. */ @@ -642,6 +901,17 @@ typedef as gcc can already see that, plus causes gcc to bomb. */ #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movl %%esp,%%edi\n\t" \ + "andl $0xfffffff0,%%esp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movl %%edi,%%esp\n\t" + /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned long) == 4. */ @@ -652,11 +922,13 @@ typedef volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -669,13 +941,15 @@ typedef _argvec[0] = (unsigned long)_orig.nraddr; \ _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $4, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -689,14 +963,16 @@ typedef _argvec[1] = (unsigned long)(arg1); \ _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $8, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -711,15 +987,17 @@ typedef _argvec[2] = (unsigned long)(arg2); \ _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $12, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -735,16 +1013,17 @@ typedef _argvec[3] = (unsigned long)(arg3); \ _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ "pushl 8(%%eax)\n\t" \ "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -761,6 +1040,8 @@ typedef _argvec[4] = (unsigned long)(arg4); \ _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ "pushl 12(%%eax)\n\t" \ @@ -768,10 +1049,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $20, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -789,6 +1070,8 @@ typedef _argvec[5] = (unsigned long)(arg5); \ _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ "pushl 16(%%eax)\n\t" \ @@ -797,10 +1080,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $24, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -820,6 +1103,8 @@ typedef _argvec[6] = (unsigned long)(arg6); \ _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ "pushl 20(%%eax)\n\t" \ @@ -829,10 +1114,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $28, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -853,6 +1138,7 @@ typedef _argvec[7] = (unsigned long)(arg7); \ _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ "pushl 24(%%eax)\n\t" \ @@ -863,10 +1149,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -888,6 +1174,8 @@ typedef _argvec[8] = (unsigned long)(arg8); \ _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $12, %%esp\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ "pushl 28(%%eax)\n\t" \ @@ -899,10 +1187,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $36, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -925,6 +1213,8 @@ typedef _argvec[9] = (unsigned long)(arg9); \ _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $8, %%esp\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ "pushl 32(%%eax)\n\t" \ @@ -937,10 +1227,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $40, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -965,6 +1255,8 @@ typedef _argvec[10] = (unsigned long)(arg10); \ _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ + "subl $4, %%esp\n\t" \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ "pushl 36(%%eax)\n\t" \ @@ -978,10 +1270,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $44, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1007,6 +1299,7 @@ typedef _argvec[11] = (unsigned long)(arg11); \ _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "pushl 48(%%eax)\n\t" \ "pushl 44(%%eax)\n\t" \ "pushl 40(%%eax)\n\t" \ @@ -1021,10 +1314,10 @@ typedef "pushl 4(%%eax)\n\t" \ "movl (%%eax), %%eax\n\t" /* target->%eax */ \ VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=a" (_res) \ : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1041,6 +1334,88 @@ typedef #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ "rdi", "r8", "r9", "r10", "r11" +/* This is all pretty complex. It's so as to make stack unwinding + work reliably. See bug 243270. The basic problem is the sub and + add of 128 of %rsp in all of the following macros. If gcc believes + the CFA is in %rsp, then unwinding may fail, because what's at the + CFA is not what gcc "expected" when it constructs the CFIs for the + places where the macros are instantiated. + + But we can't just add a CFI annotation to increase the CFA offset + by 128, to match the sub of 128 from %rsp, because we don't know + whether gcc has chosen %rsp as the CFA at that point, or whether it + has chosen some other register (eg, %rbp). In the latter case, + adding a CFI annotation to change the CFA offset is simply wrong. + + So the solution is to get hold of the CFA using + __builtin_dwarf_cfa(), put it in a known register, and add a + CFI annotation to say what the register is. We choose %rbp for + this (perhaps perversely), because: + + (1) %rbp is already subject to unwinding. If a new register was + chosen then the unwinder would have to unwind it in all stack + traces, which is expensive, and + + (2) %rbp is already subject to precise exception updates in the + JIT. If a new register was chosen, we'd have to have precise + exceptions for it too, which reduces performance of the + generated code. + + However .. one extra complication. We can't just whack the result + of __builtin_dwarf_cfa() into %rbp and then add %rbp to the + list of trashed registers at the end of the inline assembly + fragments; gcc won't allow %rbp to appear in that list. Hence + instead we need to stash %rbp in %r15 for the duration of the asm, + and say that %r15 is trashed instead. gcc seems happy to go with + that. + + Oh .. and this all needs to be conditionalised so that it is + unchanged from before this commit, when compiled with older gccs + that don't support __builtin_dwarf_cfa. Furthermore, since + this header file is freestanding, it has to be independent of + config.h, and so the following conditionalisation cannot depend on + configure time checks. + + Although it's not clear from + 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', + this expression excludes Darwin. + .cfi directives in Darwin assembly appear to be completely + different and I haven't investigated how they work. + + For even more entertainment value, note we have to use the + completely undocumented __builtin_dwarf_cfa(), which appears to + really compute the CFA, whereas __builtin_frame_address(0) claims + to but actually doesn't. See + https://bugs.kde.org/show_bug.cgi?id=243270#c47 +*/ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"r"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + "movq %%rbp, %%r15\n\t" \ + "movq %2, %%rbp\n\t" \ + ".cfi_remember_state\n\t" \ + ".cfi_def_cfa rbp, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "movq %%r15, %%rbp\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE +# define VALGRIND_CFI_EPILOGUE +#endif + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "movq %%rsp,%%r14\n\t" \ + "andq $0xfffffffffffffff0,%%rsp\n\t" +#define VALGRIND_RESTORE_STACK \ + "movq %%r14,%%rsp\n\t" + /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned long) == 8. */ @@ -1060,11 +1435,496 @@ typedef redzone, for the duration of the hidden call, to make it safe. Probably the same problem afflicts the other redzone-style ABIs too - (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is + (ppc64-linux); but for those, the stack is self describing (none of this CFI nonsense) so at least messing with the stack pointer doesn't give a danger of non-unwindable stack. */ +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $136,%%rsp\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11,arg12) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + VALGRIND_ALIGN_STACK \ + "subq $128,%%rsp\n\t" \ + "pushq 96(%%rax)\n\t" \ + "pushq 88(%%rax)\n\t" \ + "pushq 80(%%rax)\n\t" \ + "pushq 72(%%rax)\n\t" \ + "pushq 64(%%rax)\n\t" \ + "pushq 56(%%rax)\n\t" \ + "movq 48(%%rax), %%r9\n\t" \ + "movq 40(%%rax), %%r8\n\t" \ + "movq 32(%%rax), %%rcx\n\t" \ + "movq 24(%%rax), %%rdx\n\t" \ + "movq 16(%%rax), %%rsi\n\t" \ + "movq 8(%%rax), %%rdi\n\t" \ + "movq (%%rax), %%rax\n\t" /* target->%rax */ \ + VALGRIND_CALL_NOREDIR_RAX \ + VALGRIND_RESTORE_STACK \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=a" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ + +/* ------------------------ ppc32-linux ------------------------ */ + +#if defined(PLAT_ppc32_linux) + +/* This is useful for finding out about the on-stack stuff: + + extern int f9 ( int,int,int,int,int,int,int,int,int ); + extern int f10 ( int,int,int,int,int,int,int,int,int,int ); + extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); + extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); + + int g9 ( void ) { + return f9(11,22,33,44,55,66,77,88,99); + } + int g10 ( void ) { + return f10(11,22,33,44,55,66,77,88,99,110); + } + int g11 ( void ) { + return f11(11,22,33,44,55,66,77,88,99,110,121); + } + int g12 ( void ) { + return f12(11,22,33,44,55,66,77,88,99,110,121,132); + } +*/ + +/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ + +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS \ + "lr", "ctr", "xer", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ + "r11", "r12", "r13" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rlwinm 1,1,0,0,27\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc32-linux, + sizeof(unsigned long) == 4. */ + #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ @@ -1072,13 +1932,15 @@ typedef volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1089,38 +1951,42 @@ typedef volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ + _argvec[1] = (unsigned long)arg1; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1131,20 +1997,22 @@ typedef volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1155,22 +2023,24 @@ typedef volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1181,24 +2051,26 @@ typedef volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1209,26 +2081,28 @@ typedef volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CALL_NOREDIR_RAX \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1240,29 +2114,30 @@ typedef volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $8, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1274,31 +2149,32 @@ typedef volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $16, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1310,33 +2186,38 @@ typedef volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $24, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1348,77 +2229,93 @@ typedef volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $32, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-16\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) + +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ + arg7,arg8,arg9,arg10,arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $40, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1430,69 +2327,59 @@ typedef volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 96(%%rax)\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $48, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + VALGRIND_ALIGN_STACK \ + "mr 11,%1\n\t" \ + "addi 1,1,-32\n\t" \ + /* arg12 */ \ + "lwz 3,48(11)\n\t" \ + "stw 3,20(1)\n\t" \ + /* arg11 */ \ + "lwz 3,44(11)\n\t" \ + "stw 3,16(1)\n\t" \ + /* arg10 */ \ + "lwz 3,40(11)\n\t" \ + "stw 3,12(1)\n\t" \ + /* arg9 */ \ + "lwz 3,36(11)\n\t" \ + "stw 3,8(1)\n\t" \ + /* args1-8 */ \ + "lwz 3,4(11)\n\t" /* arg1->r3 */ \ + "lwz 4,8(11)\n\t" \ + "lwz 5,12(11)\n\t" \ + "lwz 6,16(11)\n\t" /* arg4->r6 */ \ + "lwz 7,20(11)\n\t" \ + "lwz 8,24(11)\n\t" \ + "lwz 9,28(11)\n\t" \ + "lwz 10,32(11)\n\t" /* arg8->r10 */ \ + "lwz 11,0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + VALGRIND_RESTORE_STACK \ + "mr %0,3" \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -/* This is useful for finding out about the on-stack stuff: +#endif /* PLAT_ppc32_linux */ - extern int f9 ( int,int,int,int,int,int,int,int,int ); - extern int f10 ( int,int,int,int,int,int,int,int,int,int ); - extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); - extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); +/* ------------------------ ppc64-linux ------------------------ */ - int g9 ( void ) { - return f9(11,22,33,44,55,66,77,88,99); - } - int g10 ( void ) { - return f10(11,22,33,44,55,66,77,88,99,110); - } - int g11 ( void ) { - return f11(11,22,33,44,55,66,77,88,99,110,121); - } - int g12 ( void ) { - return f12(11,22,33,44,55,66,77,88,99,110,121,132); - } -*/ +#if defined(PLAT_ppc64_linux) /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ @@ -1503,23 +2390,42 @@ typedef "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ "r11", "r12", "r13" -/* These CALL_FN_ macros assume that on ppc32-linux, - sizeof(unsigned long) == 4. */ +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +#define VALGRIND_ALIGN_STACK \ + "mr 28,1\n\t" \ + "rldicr 1,1,0,59\n\t" +#define VALGRIND_RESTORE_STACK \ + "mr 1,28\n\t" + +/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned + long) == 8. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ + volatile unsigned long _argvec[3+0]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1527,19 +2433,27 @@ typedef #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ + volatile unsigned long _argvec[3+1]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1547,21 +2461,29 @@ typedef #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ + volatile unsigned long _argvec[3+2]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1569,23 +2491,31 @@ typedef #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ + volatile unsigned long _argvec[3+3]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1593,25 +2523,33 @@ typedef #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ + volatile unsigned long _argvec[3+4]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1619,27 +2557,35 @@ typedef #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ + volatile unsigned long _argvec[3+5]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1647,29 +2593,37 @@ typedef #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ + volatile unsigned long _argvec[3+6]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1678,31 +2632,39 @@ typedef arg7) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ + volatile unsigned long _argvec[3+7]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1711,33 +2673,41 @@ typedef arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ + volatile unsigned long _argvec[3+8]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1746,40 +2716,47 @@ typedef arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ + volatile unsigned long _argvec[3+9]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ + : /*out*/ "=r" (_res) \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1788,44 +2765,51 @@ typedef arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ + volatile unsigned long _argvec[3+10]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-128\n\t" /* expand stack frame */ \ /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1834,48 +2818,55 @@ typedef arg7,arg8,arg9,arg10,arg11) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ + volatile unsigned long _argvec[3+11]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1884,94 +2875,111 @@ typedef arg7,arg8,arg9,arg10,arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ + volatile unsigned long _argvec[3+12]; \ volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ + /* _argvec[0] holds current r2 across the call */ \ + _argvec[1] = (unsigned long)_orig.r2; \ + _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[2+1] = (unsigned long)arg1; \ + _argvec[2+2] = (unsigned long)arg2; \ + _argvec[2+3] = (unsigned long)arg3; \ + _argvec[2+4] = (unsigned long)arg4; \ + _argvec[2+5] = (unsigned long)arg5; \ + _argvec[2+6] = (unsigned long)arg6; \ + _argvec[2+7] = (unsigned long)arg7; \ + _argvec[2+8] = (unsigned long)arg8; \ + _argvec[2+9] = (unsigned long)arg9; \ + _argvec[2+10] = (unsigned long)arg10; \ + _argvec[2+11] = (unsigned long)arg11; \ + _argvec[2+12] = (unsigned long)arg12; \ __asm__ volatile( \ + VALGRIND_ALIGN_STACK \ "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ + "std 2,-16(11)\n\t" /* save tocptr */ \ + "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ + "addi 1,1,-144\n\t" /* expand stack frame */ \ /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,20(1)\n\t" \ + "ld 3,96(11)\n\t" \ + "std 3,136(1)\n\t" \ /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ + "ld 3,88(11)\n\t" \ + "std 3,128(1)\n\t" \ /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ + "ld 3,80(11)\n\t" \ + "std 3,120(1)\n\t" \ /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ + "ld 3,72(11)\n\t" \ + "std 3,112(1)\n\t" \ /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ + "ld 3, 8(11)\n\t" /* arg1->r3 */ \ + "ld 4, 16(11)\n\t" /* arg2->r4 */ \ + "ld 5, 24(11)\n\t" /* arg3->r5 */ \ + "ld 6, 32(11)\n\t" /* arg4->r6 */ \ + "ld 7, 40(11)\n\t" /* arg5->r7 */ \ + "ld 8, 48(11)\n\t" /* arg6->r8 */ \ + "ld 9, 56(11)\n\t" /* arg7->r9 */ \ + "ld 10, 64(11)\n\t" /* arg8->r10 */ \ + "ld 11, 0(11)\n\t" /* target->r11 */ \ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ + "mr 11,%1\n\t" \ + "mr %0,3\n\t" \ + "ld 2,-16(11)\n\t" /* restore tocptr */ \ + VALGRIND_RESTORE_STACK \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "r" (&_argvec[2]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ +#endif /* PLAT_ppc64_linux */ -#if defined(PLAT_ppc64_linux) +/* ------------------------- arm-linux ------------------------- */ -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ +#if defined(PLAT_arm_linux) /* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ +#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" + +/* Macros to save and align the stack before making a function + call and restore it afterwards as gcc may not keep the stack + pointer aligned if it doesn't realise calls are being made + to other functions. */ + +/* This is a bit tricky. We store the original stack pointer in r10 + as it is callee-saves. gcc doesn't allow the use of r11 for some + reason. Also, we can't directly "bic" the stack pointer in thumb + mode since r13 isn't an allowed register number in that context. + So use r4 as a temporary, since that is about to get trashed + anyway, just after each use of this macro. Side effect is we need + to be very careful about any future changes, since + VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ +#define VALGRIND_ALIGN_STACK \ + "mov r10, sp\n\t" \ + "mov r4, sp\n\t" \ + "bic r4, r4, #7\n\t" \ + "mov sp, r4\n\t" +#define VALGRIND_RESTORE_STACK \ + "mov sp, r10\n\t" + +/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned + long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -1979,25 +2987,20 @@ typedef #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2005,27 +3008,22 @@ typedef #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2033,29 +3031,24 @@ typedef #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2063,31 +3056,26 @@ typedef #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2095,33 +3083,30 @@ typedef #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2129,35 +3114,31 @@ typedef #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2166,37 +3147,34 @@ typedef arg7) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2205,39 +3183,35 @@ typedef arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "push {r0, r1, r2, r3} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2246,46 +3220,38 @@ typedef arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -2294,781 +3260,659 @@ typedef arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "push {r0} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ + VALGRIND_ALIGN_STACK \ + "sub sp, sp, #4 \n\t" \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "push {r0, r1} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ + VALGRIND_ALIGN_STACK \ + "ldr r0, [%1, #40] \n\t" \ + "ldr r1, [%1, #44] \n\t" \ + "ldr r2, [%1, #48] \n\t" \ + "push {r0, r1, r2} \n\t" \ + "ldr r0, [%1, #20] \n\t" \ + "ldr r1, [%1, #24] \n\t" \ + "ldr r2, [%1, #28] \n\t" \ + "ldr r3, [%1, #32] \n\t" \ + "ldr r4, [%1, #36] \n\t" \ + "push {r0, r1, r2, r3, r4} \n\t" \ + "ldr r0, [%1, #4] \n\t" \ + "ldr r1, [%1, #8] \n\t" \ + "ldr r2, [%1, #12] \n\t" \ + "ldr r3, [%1, #16] \n\t" \ + "ldr r4, [%1] \n\t" /* target->r4 */ \ + VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ + VALGRIND_RESTORE_STACK \ + "mov %0, r0" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_ppc64_linux */ +#endif /* PLAT_arm_linux */ + +/* ------------------------- s390x-linux ------------------------- */ + +#if defined(PLAT_s390x_linux) + +/* Similar workaround as amd64 (see above), but we use r11 as frame + pointer and save the old r11 in r7. r11 might be used for + argvec, therefore we copy argvec in r1 since r1 is clobbered + after the call anyway. */ +#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) +# define __FRAME_POINTER \ + ,"d"(__builtin_dwarf_cfa()) +# define VALGRIND_CFI_PROLOGUE \ + ".cfi_remember_state\n\t" \ + "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ + "lgr 7,11\n\t" \ + "lgr 11,%2\n\t" \ + ".cfi_def_cfa r11, 0\n\t" +# define VALGRIND_CFI_EPILOGUE \ + "lgr 11, 7\n\t" \ + ".cfi_restore_state\n\t" +#else +# define __FRAME_POINTER +# define VALGRIND_CFI_PROLOGUE \ + "lgr 1,%1\n\t" +# define VALGRIND_CFI_EPILOGUE +#endif -/* ------------------------ ppc32-aix5 ------------------------- */ +/* Nb: On s390 the stack pointer is properly aligned *at all times* + according to the s390 GCC maintainer. (The ABI specification is not + precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and + VALGRIND_RESTORE_STACK are not defined here. */ + +/* These regs are trashed by the hidden call. Note that we overwrite + r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the + function a proper return address. All others are ABI defined call + clobbers. */ +#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ + "f0","f1","f2","f3","f4","f5","f6","f7" + +/* Nb: Although r11 is modified in the asm snippets below (inside + VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for + two reasons: + (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not + modified + (2) GCC will complain that r11 cannot appear inside a clobber section, + when compiled with -O -fno-omit-frame-pointer + */ + +#define CALL_FN_W_v(lval, orig) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[1]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 1, 0(1)\n\t" /* target->r1 */ \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -#if defined(PLAT_ppc32_aix5) +/* The call abi has the arguments in r2-r6 and stack */ +#define CALL_FN_W_W(lval, orig, arg1) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[2]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ +#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[3]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" +#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[4]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ +#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[5]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "lwz 3," #_n_fr "(1)\n\t" \ - "stw 3,0(1)\n\t" +#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[6]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-160\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,160\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" +#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[7]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-168\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,168\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned - long) == 4. */ +#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[8]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-176\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,176\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ + } while (0) -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ +#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[9]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-184\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,184\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ +#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[10]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-192\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,192\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ +#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[11]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-200\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,200\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ +#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11) \ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[12]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-208\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,208\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ +#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ + do { \ + volatile OrigFn _orig = (orig); \ + volatile unsigned long _argvec[13]; \ + volatile unsigned long _res; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)arg1; \ + _argvec[2] = (unsigned long)arg2; \ + _argvec[3] = (unsigned long)arg3; \ + _argvec[4] = (unsigned long)arg4; \ + _argvec[5] = (unsigned long)arg5; \ + _argvec[6] = (unsigned long)arg6; \ + _argvec[7] = (unsigned long)arg7; \ + _argvec[8] = (unsigned long)arg8; \ + _argvec[9] = (unsigned long)arg9; \ + _argvec[10] = (unsigned long)arg10; \ + _argvec[11] = (unsigned long)arg11; \ + _argvec[12] = (unsigned long)arg12; \ + __asm__ volatile( \ + VALGRIND_CFI_PROLOGUE \ + "aghi 15,-216\n\t" \ + "lg 2, 8(1)\n\t" \ + "lg 3,16(1)\n\t" \ + "lg 4,24(1)\n\t" \ + "lg 5,32(1)\n\t" \ + "lg 6,40(1)\n\t" \ + "mvc 160(8,15), 48(1)\n\t" \ + "mvc 168(8,15), 56(1)\n\t" \ + "mvc 176(8,15), 64(1)\n\t" \ + "mvc 184(8,15), 72(1)\n\t" \ + "mvc 192(8,15), 80(1)\n\t" \ + "mvc 200(8,15), 88(1)\n\t" \ + "mvc 208(8,15), 96(1)\n\t" \ + "lg 1, 0(1)\n\t" \ + VALGRIND_CALL_NOREDIR_R1 \ + "lgr %0, 2\n\t" \ + "aghi 15,216\n\t" \ + VALGRIND_CFI_EPILOGUE \ + : /*out*/ "=d" (_res) \ + : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ + ); \ + lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,68(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_aix5 */ - -/* ------------------------ ppc64-aix5 ------------------------- */ - -#if defined(PLAT_ppc64_aix5) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ +#endif /* PLAT_s390x_linux */ -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "ld 3," #_n_fr "(1)\n\t" \ - "std 3,0(1)\n\t" +/* ------------------------- mips-linux ------------------------- */ + +#if defined(PLAT_mips32_linux) -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" +/* These regs are trashed by the hidden call. */ +#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ +"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ +"$25", "$31" -/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned - long) == 8. */ +/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned + long) == 4. */ #define CALL_FN_W_v(lval, orig) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ + volatile unsigned long _argvec[1]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16\n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3077,27 +3921,26 @@ typedef #define CALL_FN_W_W(lval, orig, arg1) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ + volatile unsigned long _argvec[2]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $a0, 4(%1) \n\t" /* arg1*/ \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ + : /*in*/ "0" (&_argvec[0]) \ + : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) @@ -3105,28 +3948,27 @@ typedef #define CALL_FN_W_WW(lval, orig, arg1,arg2) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ + volatile unsigned long _argvec[3]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3135,30 +3977,29 @@ typedef #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ + volatile unsigned long _argvec[4]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3167,32 +4008,31 @@ typedef #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ + volatile unsigned long _argvec[5]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "subu $29, $29, 16 \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 16 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $29, $29, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3201,72 +4041,73 @@ typedef #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ + volatile unsigned long _argvec[6]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 24\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $29, $29, 24 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) - #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ + volatile unsigned long _argvec[7]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 32\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "nop\n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 32 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3276,38 +4117,40 @@ typedef arg7) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ + volatile unsigned long _argvec[8]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 32\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 32 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3317,40 +4160,43 @@ typedef arg7,arg8) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ + volatile unsigned long _argvec[9]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 40\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 32(%1) \n\t" \ + "sw $a0, 28($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 40 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3360,47 +4206,46 @@ typedef arg7,arg8,arg9) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ + volatile unsigned long _argvec[10]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 40\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 32(%1) \n\t" \ + "sw $a0, 28($sp) \n\t" \ + "lw $a0, 36(%1) \n\t" \ + "sw $a0, 32($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 40 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ @@ -3410,177 +4255,170 @@ typedef arg7,arg8,arg9,arg10) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ + volatile unsigned long _argvec[11]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 48\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 32(%1) \n\t" \ + "sw $a0, 28($sp) \n\t" \ + "lw $a0, 36(%1) \n\t" \ + "sw $a0, 32($sp) \n\t" \ + "lw $a0, 40(%1) \n\t" \ + "sw $a0, 36($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 48 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ +#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ + volatile unsigned long _argvec[12]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 48\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 32(%1) \n\t" \ + "sw $a0, 28($sp) \n\t" \ + "lw $a0, 36(%1) \n\t" \ + "sw $a0, 32($sp) \n\t" \ + "lw $a0, 40(%1) \n\t" \ + "sw $a0, 36($sp) \n\t" \ + "lw $a0, 44(%1) \n\t" \ + "sw $a0, 40($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 48 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ +#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ + arg6,arg7,arg8,arg9,arg10, \ + arg11,arg12) \ do { \ volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ + volatile unsigned long _argvec[13]; \ volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ + _argvec[0] = (unsigned long)_orig.nraddr; \ + _argvec[1] = (unsigned long)(arg1); \ + _argvec[2] = (unsigned long)(arg2); \ + _argvec[3] = (unsigned long)(arg3); \ + _argvec[4] = (unsigned long)(arg4); \ + _argvec[5] = (unsigned long)(arg5); \ + _argvec[6] = (unsigned long)(arg6); \ + _argvec[7] = (unsigned long)(arg7); \ + _argvec[8] = (unsigned long)(arg8); \ + _argvec[9] = (unsigned long)(arg9); \ + _argvec[10] = (unsigned long)(arg10); \ + _argvec[11] = (unsigned long)(arg11); \ + _argvec[12] = (unsigned long)(arg12); \ __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ + "subu $29, $29, 8 \n\t" \ + "sw $gp, 0($sp) \n\t" \ + "sw $ra, 4($sp) \n\t" \ + "lw $a0, 20(%1) \n\t" \ + "subu $sp, $sp, 56\n\t" \ + "sw $a0, 16($sp) \n\t" \ + "lw $a0, 24(%1) \n\t" \ + "sw $a0, 20($sp) \n\t" \ + "lw $a0, 28(%1) \n\t" \ + "sw $a0, 24($sp) \n\t" \ + "lw $a0, 32(%1) \n\t" \ + "sw $a0, 28($sp) \n\t" \ + "lw $a0, 36(%1) \n\t" \ + "sw $a0, 32($sp) \n\t" \ + "lw $a0, 40(%1) \n\t" \ + "sw $a0, 36($sp) \n\t" \ + "lw $a0, 44(%1) \n\t" \ + "sw $a0, 40($sp) \n\t" \ + "lw $a0, 48(%1) \n\t" \ + "sw $a0, 44($sp) \n\t" \ + "lw $a0, 4(%1) \n\t" \ + "lw $a1, 8(%1) \n\t" \ + "lw $a2, 12(%1) \n\t" \ + "lw $a3, 16(%1) \n\t" \ + "lw $t9, 0(%1) \n\t" /* target->t9 */ \ + VALGRIND_CALL_NOREDIR_T9 \ + "addu $sp, $sp, 56 \n\t" \ + "lw $gp, 0($sp) \n\t" \ + "lw $ra, 4($sp) \n\t" \ + "addu $sp, $sp, 8 \n\t" \ + "move %0, $v0\n" \ : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ + : /*in*/ "0" (&_argvec[0]) \ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ ); \ lval = (__typeof__(lval)) _res; \ } while (0) -#endif /* PLAT_ppc64_aix5 */ +#endif /* PLAT_mips32_linux */ /* ------------------------------------------------------------------ */ @@ -3626,9 +4464,14 @@ typedef errors. */ VG_USERREQ__COUNT_ERRORS = 0x1201, + /* Allows a string (gdb monitor command) to be passed to the tool + Used for interaction with vgdb/gdb */ + VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, + /* These are useful and can be interpreted by any tool that tracks malloc() et al, by using vg_replace_malloc.c. */ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, + VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, VG_USERREQ__FREELIKE_BLOCK = 0x1302, /* Memory pool support. */ VG_USERREQ__CREATE_MEMPOOL = 0x1303, @@ -3641,8 +4484,17 @@ typedef VG_USERREQ__MEMPOOL_EXISTS = 0x130a, /* Allow printfs to valgrind log. */ + /* The first two pass the va_list argument by value, which + assumes it is the same size as or smaller than a UWord, + which generally isn't the case. Hence are deprecated. + The second two pass the vargs by reference and so are + immune to this problem. */ + /* both :: char* fmt, va_list vargs (DEPRECATED) */ VG_USERREQ__PRINTF = 0x1401, VG_USERREQ__PRINTF_BACKTRACE = 0x1402, + /* both :: char* fmt, va_list* vargs */ + VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, /* Stack support. */ VG_USERREQ__STACK_REGISTER = 0x1501, @@ -3650,39 +4502,44 @@ typedef VG_USERREQ__STACK_CHANGE = 0x1503, /* Wine support */ - VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601 + VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, + + /* Querying of debug info. */ + VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, + + /* Disable/enable error reporting level. Takes a single + Word arg which is the delta to this thread's error + disablement indicator. Hence 1 disables or further + disables errors, and -1 moves back towards enablement. + Other values are not allowed. */ + VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801, + + /* Initialise IR injection */ + VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901 } Vg_ClientRequest; #if !defined(__GNUC__) # define __extension__ /* */ #endif + /* Returns the number of Valgrinds this code is running under. That is, 0 if running natively, 1 if running under Valgrind, 2 if running under Valgrind which is running under another Valgrind, etc. */ -#if defined(HOST_WIN32) || defined(TARGET_WIN32) -#define RUNNING_ON_VALGRIND 0 -#else -#define RUNNING_ON_VALGRIND __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0, 0); \ - _qzz_res; \ - }) -#endif +#define RUNNING_ON_VALGRIND \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ + VG_USERREQ__RUNNING_ON_VALGRIND, \ + 0, 0, 0, 0, 0) \ + /* Discard translation of code in the range [_qzz_addr .. _qzz_addr + _qzz_len - 1]. Useful if you are debugging a JITter or some such, since it provides a way to make sure valgrind will retranslate the invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - } +#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ + _qzz_addr, _qzz_len, 0, 0, 0) /* These requests are for getting Valgrind itself to print something. @@ -3690,46 +4547,83 @@ typedef is the number of characters printed, excluding the "**** " part at the start and the backtrace (if present). */ -#if defined(NVALGRIND) - -# define VALGRIND_PRINTF(...) -# define VALGRIND_PRINTF_BACKTRACE(...) - -#else /* NVALGRIND */ - +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) /* Modern GCC will optimize the static routine out if unused, and unused attribute will shut down warnings about it. */ static int VALGRIND_PRINTF(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); +#endif static int +#if defined(_MSC_VER) +__inline +#endif VALGRIND_PRINTF(const char *format, ...) { +#if defined(NVALGRIND) + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) + uintptr_t _qzz_res; +#else unsigned long _qzz_res; +#endif va_list vargs; va_start(vargs, format); - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF, - (unsigned long)format, (unsigned long)vargs, +#if defined(_MSC_VER) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, 0, 0, 0); +#endif va_end(vargs); return (int)_qzz_res; +#endif /* NVALGRIND */ } +#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) __attribute__((format(__printf__, 1, 2), __unused__)); +#endif static int +#if defined(_MSC_VER) +__inline +#endif VALGRIND_PRINTF_BACKTRACE(const char *format, ...) { +#if defined(NVALGRIND) + return 0; +#else /* NVALGRIND */ +#if defined(_MSC_VER) + uintptr_t _qzz_res; +#else unsigned long _qzz_res; +#endif va_list vargs; va_start(vargs, format); - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE, - (unsigned long)format, (unsigned long)vargs, +#if defined(_MSC_VER) + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (uintptr_t)format, + (uintptr_t)&vargs, + 0, 0, 0); +#else + _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, + VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, + (unsigned long)format, + (unsigned long)&vargs, 0, 0, 0); +#endif va_end(vargs); return (int)_qzz_res; -} - #endif /* NVALGRIND */ +} /* These requests allow control to move from the simulated CPU to the @@ -3756,58 +4650,39 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) with a lot in the past. */ #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0, 0); \ - _qyy_res; \ - }) + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL0, \ + _qyy_fn, \ + 0, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL1, \ + _qyy_fn, \ + _qyy_arg1, 0, 0, 0) + +#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL2, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, 0, 0) #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, \ - _qyy_arg3, 0); \ - _qyy_res; \ - }) + VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ + VG_USERREQ__CLIENT_CALL3, \ + _qyy_fn, \ + _qyy_arg1, _qyy_arg2, \ + _qyy_arg3, 0) /* Counts the number of errors that have been recorded by a tool. Nb: the tool must record the errors with VG_(maybe_record_error)() or VG_(unique_error)() for them to be counted. */ #define VALGRIND_COUNT_ERRORS \ - __extension__ \ - ({unsigned int _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ + 0 /* default return */, \ VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0, 0); \ - _qyy_res; \ - }) + 0, 0, 0, 0, 0) /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing when heap blocks are allocated in order to give accurate results. This @@ -3873,7 +4748,24 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a heap block is deallocated. - In many cases, these two client requests will not be enough to get your + VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For + Memcheck, it does four things: + + - It records that the size of a block has been changed. This assumes that + the block was annotated as having been allocated via + VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. + + - If the block shrunk, it marks the freed memory as being unaddressable. + + - If the block grew, it marks the new area as undefined and defines a red + zone past the end of the new block. + + - The V-bits of the overlap between the old and the new block are preserved. + + VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block + and before deallocation of the old block. + + In many cases, these three client requests will not be enough to get your allocator working well with Memcheck. More specifically, if your allocator writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call will be necessary to mark the memory as addressable just before the zeroing @@ -3891,138 +4783,125 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...) understand the distinction between the allocator and the rest of the program. - Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request; it - has to be emulated with MALLOCLIKE/FREELIKE and memory copying. - Ignored if addr == 0. */ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed, 0); \ - } +#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ + addr, sizeB, rzB, is_zeroed, 0) /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. Ignored if addr == 0. */ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0, 0); \ - } +#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ + addr, oldSizeB, newSizeB, rzB, 0) + +/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. + Ignored if addr == 0. +*/ +#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ + addr, rzB, 0, 0, 0) /* Create a memory pool. */ #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ + pool, rzB, is_zeroed, 0, 0) /* Destroy a memory pool. */ #define VALGRIND_DESTROY_MEMPOOL(pool) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ + pool, 0, 0, 0, 0) /* Associate a piece of memory with a memory pool. */ #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ + pool, addr, size, 0, 0) /* Disassociate a piece of memory from a memory pool. */ #define VALGRIND_MEMPOOL_FREE(pool, addr) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ + pool, addr, 0, 0, 0) /* Disassociate any pieces outside a particular range. */ #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_TRIM, \ - pool, addr, size, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ + pool, addr, size, 0, 0) /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MOVE_MEMPOOL, \ - poolA, poolB, 0, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ + poolA, poolB, 0, 0, 0) /* Resize and/or move a piece associated with a memory pool. */ #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_CHANGE, \ - pool, addrA, addrB, size, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ + pool, addrA, addrB, size, 0) /* Return 1 if a mempool exists, else 0. */ #define VALGRIND_MEMPOOL_EXISTS(pool) \ - __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ VG_USERREQ__MEMPOOL_EXISTS, \ - pool, 0, 0, 0, 0); \ - _qzz_res; \ - }) + pool, 0, 0, 0, 0) /* Mark a piece of memory as being a stack. Returns a stack id. */ #define VALGRIND_STACK_REGISTER(start, end) \ - __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ VG_USERREQ__STACK_REGISTER, \ - start, end, 0, 0, 0); \ - _qzz_res; \ - }) + start, end, 0, 0, 0) /* Unmark the piece of memory associated with a stack id as being a stack. */ #define VALGRIND_STACK_DEREGISTER(id) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_DEREGISTER, \ - id, 0, 0, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ + id, 0, 0, 0, 0) /* Change the start and end address of the stack id. */ #define VALGRIND_STACK_CHANGE(id, start, end) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_CHANGE, \ - id, start, end, 0, 0); \ - } + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ + id, start, end, 0, 0) /* Load PDB debug info for Wine PE image_map. */ -#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__LOAD_PDB_DEBUGINFO, \ - fd, ptr, total_size, delta, 0); \ - } - - +#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ + fd, ptr, total_size, delta, 0) + +/* Map a code address to a source file name and line number. buf64 + must point to a 64-byte buffer in the caller's address space. The + result will be dumped in there and is guaranteed to be zero + terminated. If no info is found, the first byte is set to zero. */ +#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ + (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ + VG_USERREQ__MAP_IP_TO_SRCLOC, \ + addr, buf64, 0, 0, 0) + +/* Disable error reporting for this thread. Behaves in a stack like + way, so you can safely call this multiple times provided that + VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times + to re-enable reporting. The first call of this macro disables + reporting. Subsequent calls have no effect except to increase the + number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable + reporting. Child threads do not inherit this setting from their + parents -- they are always created with reporting enabled. */ +#define VALGRIND_DISABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + 1, 0, 0, 0, 0) + +/* Re-enable error reporting, as per comments on + VALGRIND_DISABLE_ERROR_REPORTING. */ +#define VALGRIND_ENABLE_ERROR_REPORTING \ + VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ + -1, 0, 0, 0, 0) + +#undef PLAT_x86_darwin +#undef PLAT_amd64_darwin +#undef PLAT_x86_win32 #undef PLAT_x86_linux #undef PLAT_amd64_linux #undef PLAT_ppc32_linux #undef PLAT_ppc64_linux -#undef PLAT_ppc32_aix5 -#undef PLAT_ppc64_aix5 +#undef PLAT_arm_linux +#undef PLAT_s390x_linux +#undef PLAT_mips32_linux -#else /* __GNUC__ */ -#define RUNNING_ON_VALGRIND 0 -#endif #endif /* __VALGRIND_H */ diff --git a/runtime/Makefile.am b/runtime/Makefile.am index cd71355c9d8..c12d4a7c896 100644 --- a/runtime/Makefile.am +++ b/runtime/Makefile.am @@ -34,6 +34,9 @@ moon-do-basic-clean: cd $(mcs_topdir)/ && $(MAKE) NO_DIR_CHECK=1 PROFILE=moonlight_raw clean endif +if ONLY_MONOTOUCH +build_profiles = monotouch +else if ONLY_MOONLIGHT build_profiles = moonlight_raw test_profiles = moonlight_raw @@ -80,6 +83,7 @@ endif test_profiles = $(build_profiles) +endif endif if BUILD_MCS