diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f0366ca
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,64 @@
+#OS junk files
+[Tt]humbs.db
+*.DS_Store
+
+#Visual Studio files
+*.[Oo]bj
+*.user
+*.aps
+*.pch
+*.vspscc
+*.vssscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.[Cc]ache
+*.ilk
+*.log
+*.lib
+*.sbr
+*.sdf
+*.opensdf
+*.unsuccessfulbuild
+ipch/
+obj/
+[Bb]in
+[Dd]ebug*/
+[Rr]elease*/
+Ankh.NoLoad
+
+#MonoDevelop
+*.pidb
+*.userprefs
+
+#Tooling
+_ReSharper*/
+*.resharper
+[Tt]est[Rr]esult*
+*.sass-cache
+
+#Project files
+[Bb]uild/
+
+#Subversion files
+.svn
+
+# Office Temp Files
+~$*
+
+#NuGet
+packages/
+
+#ncrunch
+*ncrunch*
+*crunch*.local.xml
+
+# visual studio database projects
+*.dbmdl
+
+#Test files
+*.testsettings
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a42a2b0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,56 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ 2. You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+See FAQ for answers to frequently asked questions about this license.
+
diff --git a/README-original.md b/README-original.md
new file mode 100644
index 0000000..702bae9
--- /dev/null
+++ b/README-original.md
@@ -0,0 +1,11 @@
+F# 3.0 Compiler + Library Source Code Drop, matching Visual Studio 2012 (R) RTM binary release
+===
+
+
+The original README can be found at http://fsharppowerpack.codeplex.com/SourceControl/changeset/view/70537#1229467
+
+It has been removed to avoid confusion because the build instructions were Windows-specific.
+
+**License:** subject to terms and conditions of the Apache License, Version 2.0. A copy of the license can be found in the License.html file at the root of this distribution. By using this source code in any fashion, you are agreeing to be bound by the terms of the Apache License, Version 2.0. You must not remove this notice, or any other, from this software.
+
+**Questions?** If you have questions about the source code, please ask at the [F# Open Source Google Group](http://groups.google.com/group/fsharp-opensource). Please do not ask the Visual F# team at Microsoft for help with this source code: they like to be friendly, but they are very busy working on improving F# and need to focus on that.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8a40b2b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,205 @@
+This is the F# compiler, core library and core tools (open source edition). It uses the Apache 2.0 license.
+
+The `master` branch is for the latest version of F# (currently F# 3.0).
+
+To bootstrap the compiler, binaries built from an earlier version of this project are used.
+
+## Requirements
+
+Requires mono 2.9 or higher. Prefer Mono 3.0.
+
+On OSX, requires automake 2.69. To install from [homebrew](http://mxcl.github.com/homebrew):
+```
+brew install automake
+```
+
+
+## Building
+
+### On Linux and other Unix systems:
+The usual:
+```
+./autogen.sh
+make
+sudo make install
+```
+By default that makes optimized binaries. To make debug, use ```make CONFIG=debug```
+
+
+### On MacOS (OSX)
+
+Use a prefix to your version of Mono:
+```
+./autogen.sh --prefix=/Library/Frameworks/Mono.framework/Versions/Current/
+make
+sudo make install
+```
+By default that makes optimized binaries. To make debug, use ```make CONFIG=debug```
+
+### On Windows, using msbuild (e.g.. if .NET is installed)
+If you have only VS2012 installed, and not VS2010, you'll need to install the F# 2.0 Runtime (http://www.microsoft.com/en-us/download/details.aspx?id=13450)
+```
+cd src
+msbuild fsharp-proto-build.proj
+ngen install ..\lib\proto\4.0\fsc-proto.exe (optional)
+msbuild fsharp-library-build.proj /p:Configuration=Release
+msbuild fsharp-compiler-build.proj /p:Configuration=Release
+```
+You can also build the FSharp.Core for .NET 2.0, Mono 2.1, MonoTouch, Silverlight 5.0, Windows Phone 7.1, Portable Profile47 (net45+sl5+win8), Portable Profile88 (net4+sl4+wp71+win8) and XNA 4.0 for Xbox 360 profiles:
+```
+msbuild fsharp-library-build.proj /p:TargetFramework=net20 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=mono21 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=monotouch /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=portable-net45+sl5+win8 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=portable-net4+sl4+wp71+win8 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=sl5 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=wp7 /p:Configuration=Release
+msbuild fsharp-library-build.proj /p:TargetFramework=net40-xna40-xbox360 /p:Configuration=Release
+```
+You can also build the FSharp.Core and FSharp.Compiler.Silverlight.dll for Silverlight 5.0:
+```
+msbuild fsharp-library-build.proj /p:TargetFramework=sl5-compiler /p:Configuration=Release
+msbuild fsharp-compiler-build.proj /p:TargetFramework=sl5-compiler /p:Configuration=Release
+```
+Change to ``` /p:Configuration=Debug``` for debug binaries.
+
+### On Windows, using xbuild (e.g. if no .NET is installed and only Mono 3.0 is installed):
+
+```
+cd src
+xbuild fsharp-proto-build.proj
+xbuild fsharp-library-build.proj
+xbuild fsharp-compiler-build.proj
+```
+
+Building using xbuild does not yet lay down a Mono-ready distribution (see src/fsharp/targets.make), so should only
+be used for private development rather than preparing distributions.
+
+
+## Strong Names
+
+The FSharp.Core.dll produced is only delay-signed (Mono does not require strong names).
+If a strong-name signed FSharp.Core.dll is needed then use the one in
+```
+ lib\bootstrap\signed\3.0\v4.0\FSharp.Core.dll
+```
+
+
+## What you get
+
+Once built the main compiler binaries go in
+ lib/release/4.0
+
+There are versions of FSharp.Core for .NET 2.0, MonoAndroid, MonoTouch (Mono profile 2.1) in
+ lib/release/2.0
+ lib/release/2.1
+ lib/release/2.1monotouch
+
+On 'make install' the binaries etc. go in the prefix, e.g.
+
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.0/FSharp.Core.dll
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/2.1/FSharp.Core.dll
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.0/fsc.exe
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.0/FSharp.Compiler.dll
+ ...
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/fsc.exe
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/FSharp.Compiler.dll
+ ...
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gac/.../FSharp.Compiler.dll
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/gac/.../FSharp.Compiler.dll
+ ...
+
+plus some files for xbuild support
+
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/Microsoft\ F#/v4.0/*
+ /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/Microsoft\ SDKs/F#/3.0/Framework/*
+
+(these names are the canonical names for Microsoft.FSharp.Targets used by project files coming from Visual Studio)
+
+plus scripts
+
+ /usr/bin/fsharpc (F# compiler)
+ /usr/bin/fsharpi (F# Interactive)
+
+## Development notes
+
+###Continuous Integration Build
+
+We have a CI build set up with the JetBrains/Teamcity server as part of the F# community projects there:
+
+http://teamcity.codebetter.com/project.html?projectId=project61&tab=projectOverview
+
+@forki controls access. Right now this builds both a Mono 'make' install and a Windows 'cd src; msbuild fsharp-build.proj' build. No binaries are saved from the build, it is just for sanity checking.
+
+
+###Editing the Compiler with Visual Studio or MonoDevelop
+
+Open `all-vs2012.sln`, and edit in modes Debug or Release. The compiler takes a good while to compile and that
+can be a bit invasive to the work flow, so it's normally better to do the actual compilation from
+the command line, see above.
+
+The F# support in MonoDevelop uses an in-process background compiler. On the Mac this causes pausing garbage
+collections to kick in which makes editing the compiler in MonoDevelop awkward.
+
+### Building F# Core Unit Tests for .NET 4.x (optional)
+
+This uses the proto compiler to build the unit tests that check some parts of `FSharp.Core.dll` and `FSharp.Compiler.dll`. There is also another set of tests under `tests\fsharp`.
+
+```
+msbuild fsharp-library-unittests-build.proj /p:TargetFramework=net40
+```
+
+*Note: You must have NUnit installed to build the unit tests.*
+
+
+
+### Validation and Use
+
+Here are some simple tests to validate what you have built by checking `fsi.exe` (F# Interactive) starts up:
+
+```
+lib\debug\4.0\fsi.exe
+1 + 1;;
+\#q;;
+lib\debug\4.0\fsi.exe /help
+lib\debug\4.0\fsc.exe /help
+echo printfn "hello world" > hello.fs
+lib\debug\4.0\fsc.exe hello.fs
+hello.exe
+```
+
+### Running Compiler tests (on Windows)
+
+There are language tests under `tests\fsharp\core`. The test apparatus is primitive and unfortunately uses batch files. You can run these on Windows using:
+
+```
+cd ..\tests\fsharp\core
+..\..\build-and-run-all-installed-ilx-configs.bat results.log
+```
+
+The results file will contain one entry for each test directory, plus any reported errors.
+
+```
+tests\fsharp\core
+tests\fsharp\core\queriesCustomQueryOps
+tests\fsharp\core\queriesLeafExpressionConvert
+tests\fsharp\core\queriesNullableOperators
+tests\fsharp\core\queriesOverIEnumerable
+...
+```
+
+Some tests for LINQ queries require SQL Server be installed. A failing test will look like this:
+
+```
+ERRORLEVEL=1: in tests\fsharp\core\csfromfs\build.bat
+```
+
+You can then go to the relevant directory and run `build.bat` and `run.bat`.
+
+
+## History
+
+F# compiler sources dropped by Microsoft are available from [fsharppowerpack.codeplex.com](http://fsharppowerpack.codeplex.com).
+
+Uses bootstrapping libraries, tools and F# compiler. The `lib/bootstrap/X.0` directories contain mono-built libraries, compiler and tools that can be used to bootstrap a build. You can also supply your own via the `--with-bootstrap` option.
+
diff --git a/samples/crlish/TestApp/App.config b/samples/crlish/TestApp/App.config
new file mode 100644
index 0000000..8e15646
--- /dev/null
+++ b/samples/crlish/TestApp/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/crlish/TestApp/Program.cs b/samples/crlish/TestApp/Program.cs
new file mode 100644
index 0000000..6517c3b
--- /dev/null
+++ b/samples/crlish/TestApp/Program.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestApp
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ int i = 1 + 1;
+ Console.WriteLine(i);
+ }
+ }
+}
diff --git a/samples/crlish/TestApp/Properties/AssemblyInfo.cs b/samples/crlish/TestApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..bc9722e
--- /dev/null
+++ b/samples/crlish/TestApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestApp")]
+[assembly: AssemblyCopyright("Copyright © 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9958c0ed-5145-4c38-87ac-97c8a0f2aee6")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/samples/crlish/TestApp/TestApp.csproj b/samples/crlish/TestApp/TestApp.csproj
new file mode 100644
index 0000000..ea43450
--- /dev/null
+++ b/samples/crlish/TestApp/TestApp.csproj
@@ -0,0 +1,58 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}
+ Exe
+ Properties
+ TestApp
+ TestApp
+ v4.5
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/crlish/clrish/App.config b/samples/crlish/clrish/App.config
new file mode 100644
index 0000000..c9bdc98
--- /dev/null
+++ b/samples/crlish/clrish/App.config
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/crlish/clrish/ExecutionEngine.fs b/samples/crlish/clrish/ExecutionEngine.fs
new file mode 100644
index 0000000..8f5c420
--- /dev/null
+++ b/samples/crlish/clrish/ExecutionEngine.fs
@@ -0,0 +1,334 @@
+module ExecutionEngine
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+type InstructionResult =
+ | NoResult
+ | Return of obj
+ | Branch of ILCodeLabel
+ | ExceptionThrown of Exception
+
+
+let rec exeMethod (currentModule: ILModuleReader) (parameters: obj[]) (typeDef: ILTypeDef) (methodDef: ILMethodDef) =
+ let stack = new Stack()
+ let locals = Array.zeroCreate methodDef.Locals.Length
+
+ let exeTargetMethod (ilMethodSpec: ILMethodSpec) objPtr =
+ let innerExe ilTypeSpec =
+ let targetType, targetModule = TypeManagement.getType currentModule ilTypeSpec
+ let possibleMethods = targetType.Methods.FindByName(ilMethodSpec.Name)
+ let targetMethod = possibleMethods |> Seq.tryFind (fun x -> x.CallingSignature.ArgTypes = ilMethodSpec.FormalArgTypes)
+ match targetMethod with
+ | Some targetMethod ->
+ let parameters =
+ match objPtr with
+ | Some x ->
+ let parameters = Array.zeroCreate (stack.Count + 1)
+ stack.CopyTo(parameters, 0)
+ parameters.[stack.Count] <-x
+ parameters |> Array.rev
+ | None -> stack.ToArray()
+ MemoryManagement.pushThreadParameters parameters targetMethod
+ let result = exeMethod targetModule parameters targetType targetMethod
+ stack.Clear()
+ MemoryManagement.popThreadParameters ()
+ let result' =
+ match result with
+ | Return result ->
+ stack.Push result
+ NoResult
+ | _ -> result
+ result'
+ | None -> failwith "failed to find method %A" ilMethodSpec
+ match ilMethodSpec.EnclosingType with
+ | ILType.Void -> failwith "Unsupported type"
+ | ILType.Array (ilArrayShape, ilType) -> failwith "Unsupported type"
+ | ILType.Value (ilTypeSpec) -> innerExe ilTypeSpec
+ | ILType.Boxed (ilTypeSpec) -> innerExe ilTypeSpec
+ | ILType.Ptr (ilType) -> failwith "Unsupported type"
+ | ILType.Byref (ilType) -> failwith "Unsupported type"
+ | ILType.FunctionPointer (ilCallingSignature) -> failwith "Unsupported type"
+ | ILType.TypeVar i -> failwith "Unsupported type"
+ | ILType.Modified (required, ilTypeRef, ilType) -> failwith "Unsupported type"
+
+ let execILBlock ilBasicBlock =
+ match ilBasicBlock with
+ // Basic
+ | AI_add ->
+ let v1 = stack.Pop()
+ let v2 = stack.Pop()
+ match v1, v2 with
+ | (:? int as v1), (:? int as v2) -> stack.Push(v1 + v2)
+ | _ -> failwith "adding supported combination of types"
+ NoResult
+ | AI_add_ovf -> failwith "Instruction AI_add_ovf unsupported"
+ | AI_add_ovf_un -> failwith "Instruction AI_add_ovf_un unsupported"
+ | AI_and -> failwith "Instruction AI_and unsupported"
+ | AI_div -> failwith "Instruction AI_div unsupported"
+ | AI_div_un -> failwith "Instruction AI_div_un unsupported"
+ | AI_ceq -> failwith "Instruction AI_ceq unsupported"
+ | AI_cgt -> failwith "Instruction AI_cgt unsupported"
+ | AI_cgt_un -> failwith "Instruction AI_cgt_un unsupported"
+ | AI_clt -> failwith "Instruction AI_clt unsupported"
+ | AI_clt_un -> failwith "Instruction AI_clt_un unsupported"
+ | AI_conv (ilBasicType) -> failwith "Instruction AI_conv unsupported"
+ | AI_conv_ovf (ilBasicType) -> failwith "Instruction AI_conv_ovf unsupported"
+ | AI_conv_ovf_un (ilBasicType) -> failwith "Instruction AI_conv_ovf_un unsupported"
+ | AI_mul -> failwith "Instruction AI_mul unsupported"
+ | AI_mul_ovf -> failwith "Instruction AI_mul_ovf unsupported"
+ | AI_mul_ovf_un -> failwith "Instruction AI_mul_ovf_un unsupported"
+ | AI_rem -> failwith "Instruction AI_rem unsupported"
+ | AI_rem_un -> failwith "Instruction AI_rem_un unsupported"
+ | AI_shl -> failwith "Instruction AI_shl unsupported"
+ | AI_shr -> failwith "Instruction AI_shr unsupported"
+ | AI_shr_un -> failwith "Instruction AI_shr unsupported"
+ | AI_sub -> failwith "Instruction AI_sub unsupported"
+ | AI_sub_ovf -> failwith "Instruction AI_sub_ovf unsupported"
+ | AI_sub_ovf_un -> failwith "Instruction AI_sub_ovf_un unsupported"
+ | AI_xor -> failwith "Instruction AI_xor unsupported"
+ | AI_or -> failwith "Instruction AI_xor unsupported"
+ | AI_neg -> failwith "Instruction AI_neg unsupported"
+ | AI_not -> failwith "Instruction AI_not unsupported"
+ | AI_ldnull ->
+ stack.Push null
+ NoResult
+ | AI_dup -> failwith "Instruction AI_dup unsupported"
+ | AI_pop ->
+ stack.Pop() |> ignore
+ NoResult
+ | AI_ckfinite -> failwith "Instruction AI_ckfinite unsupported"
+ | AI_nop -> NoResult
+ | AI_ldc (ilBasicType, ilConst) ->
+ match ilConst with
+ | ILConst.I4 x -> stack.Push x
+ | ILConst.I8 x -> stack.Push x
+ | ILConst.R4 x -> stack.Push x
+ | ILConst.R8 x -> stack.Push x
+ NoResult
+
+ | I_ldarg (i) ->
+ stack.Push(parameters.[int i])
+ NoResult
+ | I_ldarga (i) ->
+ stack.Push (MemoryManagement.getParameterAddress (int i))
+ NoResult
+ | I_ldind (ilAlignment, ilVolatility, ilBasicType) -> failwith "Instruction I_ldind unsupported"
+ | I_ldloc (i) ->
+ stack.Push(locals.[int i])
+ NoResult
+
+ | I_ldloca (i) -> failwith "Instruction I_ldloca unsupported"
+ | I_starg (i) -> failwith "Instruction I_starg unsupported"
+ | I_stind (ilAlignment, ilVolatility, ilBasicType) -> failwith "Instruction I_stind unsupported"
+ | I_stloc (i) ->
+ locals.[int i] <- stack.Pop()
+ NoResult
+
+ // Control transfer
+ | I_br (ilCodeLabel) ->
+ Branch ilCodeLabel
+ | I_jmp (ilMethodSpec) -> failwith "Instruction I_jmp unsupported"
+ | I_brcmp (ilComparisonInstr, ilCodeLabel1, ilCodeLabel2) ->
+ let firstBranch =
+ match ilComparisonInstr with
+ | BI_brfalse | BI_brtrue ->
+ let v1 = stack.Pop()
+ match ilComparisonInstr with
+ | BI_brfalse ->
+ match v1 with
+ | null -> true
+ | :? bool as v1 when v1 = false -> true
+ | :? int as v1 when v1 = 0 -> true
+ | :? int16 as v1 when v1 = 0s -> true
+ | :? int64 as v1 when v1 = 0L -> true
+ | _ -> false
+ | BI_brtrue ->
+ match v1 with
+ | null -> false
+ | :? bool as v1 when v1 = true -> true
+ | :? int as v1 when v1 <> 0 -> true
+ | :? int16 as v1 when v1 <> 0s -> true
+ | :? int64 as v1 when v1 <> 0L -> true
+ | _ -> false
+ | _ -> failwith "can't happen"
+ | _ ->
+ let v1 = stack.Pop()
+ let v2 = stack.Pop()
+ match ilComparisonInstr with
+ | BI_beq -> unbox v1 = unbox v2
+ | BI_bge -> unbox v1 >= unbox v2
+ | BI_bge_un -> unbox v1 >= unbox v2
+ | BI_bgt -> unbox v1 > unbox v2
+ | BI_bgt_un -> unbox v1 > unbox v2
+ | BI_ble -> unbox v1 <= unbox v2
+ | BI_ble_un -> unbox v1 <= unbox v2
+ | BI_blt -> unbox v1 < unbox v2
+ | BI_blt_un -> unbox v1 < unbox v2
+ | BI_bne_un -> unbox v1 <> unbox v2
+ | _ -> failwith "can't happen"
+ if firstBranch then Branch ilCodeLabel1 else Branch ilCodeLabel2
+ | I_switch (ilCodeLabels,ilCodeLabel) -> failwith "Instruction I_switch unsupported" (* last label is fallthrough *)
+ | I_ret ->
+ match stack.Count, methodDef.CallingSignature.ReturnType with
+ | 0, ILType.Void -> Return null
+ | 1, _ -> Return (stack.Pop())
+ | _ -> failwith "Error unblanced stack at return instruction"
+
+ // Method call
+ | I_call (ilTailcall, ilMethodSpec, ilVarArgs) ->
+ exeTargetMethod ilMethodSpec None
+ | I_callvirt (ilTailcall, ilMethodSpec, ilVarArgs) -> failwith "Instruction I_callvirt unsupported"
+ | I_callconstraint (ilTailcall, ilType, ilMethodSpec, ilVarArgs) -> failwith "Instruction I_callconstraint unsupported"
+ | I_calli (ilTailcall, ilCallingSignature, ilVarArgs) -> failwith "Instruction I_calli unsupported"
+ | I_ldftn ilMethodSpec -> failwith "Instruction I_ldftn unsupported"
+ | I_newobj (ilMethodSpec, ilVarArgs) ->
+ let t, _ = TypeManagement.getType currentModule ilMethodSpec.EnclosingType.TypeSpec
+ let newObjRef = MemoryManagement.getBlankObject t
+
+ let result = exeTargetMethod ilMethodSpec (Some (box newObjRef))
+ result
+
+ // Exceptions
+ | I_throw -> failwith "Instruction I_throw unsupported"
+ | I_endfinally -> failwith "Instruction I_endfinally unsupported"
+ | I_endfilter -> failwith "Instruction I_endfilter unsupported"
+ | I_leave ilCodeLabel -> failwith "Instruction I_leave unsupported"
+ | I_rethrow -> failwith "Instruction I_rethrow unsupported"
+
+ // Object instructions
+ | I_ldsfld (ilVolatility, ilFieldSpec) ->
+ let t, tModule = TypeManagement.getType currentModule ilFieldSpec.EnclosingType.TypeSpec
+ let fieldValue = MemoryManagement.getStaticField tModule t ilFieldSpec (exeMethod tModule [||] t)
+ stack.Push fieldValue
+ NoResult
+ | I_ldfld (ilAlignment, ilVolatility, ilFieldSpec) -> failwith "Instruction I_ldfld unsupported"
+ | I_ldsflda (ilFieldSpec) ->
+ let t, tModule = TypeManagement.getType currentModule ilFieldSpec.EnclosingType.TypeSpec
+ let fieldAddress = MemoryManagement.getStaticFieldAddress tModule t ilFieldSpec (exeMethod tModule [||] t)
+ stack.Push fieldAddress
+ NoResult
+ | I_ldflda (ilFieldSpec) -> failwith "Instruction I_ldflda unsupported"
+ | I_stsfld (ilVolatility, ilFieldSpec) -> failwith "Instruction I_stsfld unsupported"
+ | I_stfld (ilAlignment, ilVolatility, ilFieldSpec) ->
+ let value = stack.Pop()
+ let objRef = stack.Pop() :?> int
+ MemoryManagement.storeValueInObjectField objRef value currentModule ilFieldSpec
+ NoResult
+ | I_ldstr (stringToLoad) -> failwith "Instruction I_ldstr unsupported"
+ | I_isinst (ilType) -> failwith "Instruction I_isinst unsupported"
+ | I_castclass (ilType) -> failwith "Instruction I_castclass unsupported"
+ | I_ldtoken (ilToken) -> failwith "Instruction I_ldtoken unsupported"
+ | I_ldvirtftn (ilMethodSpec) -> failwith "Instruction I_ldvirtftn unsupported"
+
+ // Value type instructions
+ | I_cpobj (ilType) -> failwith "Instruction I_cpobj unsupported"
+ | I_initobj (ilType) -> failwith "Instruction I_initobj unsupported"
+ | I_ldobj (ilAlignment, ilVolatility, ilType) -> failwith "Instruction I_ldobj unsupported"
+ | I_stobj (ilAlignment, ilVolatility, ilType) -> failwith "Instruction I_stobj unsupported"
+ | I_box (ilType) ->
+ let value = stack.Pop()
+ let addr = MemoryManagement.storeBoxedValue value
+ stack.Push addr
+ NoResult
+ | I_unbox (ilType) -> failwith "Instruction I_unbox unsupported"
+ | I_unbox_any (ilType) -> failwith "Instruction I_unbox_any unsupported"
+ | I_sizeof (ilType) -> failwith "Instruction I_sizeof unsupported"
+
+ // Generalized array instructions. In AbsIL these instructions include
+ // both the single-dimensional variants (with ILArrayShape == ILArrayShape.SingleDimensional)
+ // and calls to the "special" multi-dimensional "methods" such as
+ // newobj void string[,]::.ctor(int32, int32)
+ // call string string[,]::Get(int32, int32)
+ // call string& string[,]::Address(int32, int32)
+ // call void string[,]::Set(int32, int32,string)
+ // The IL reader transforms calls of this form to the corresponding
+ // generalized instruction with the corresponding ILArrayShape
+ // argument. This is done to simplify the IL and make it more uniform.
+ // The IL writer then reverses this when emitting the binary.
+ | I_ldelem (ilBasicType) -> failwith "Instruction I_ldelem unsupported"
+ | I_stelem (ilBasicType) -> failwith "Instruction I_stelem unsupported"
+ | I_ldelema (ilReadonly, whatDoesThisBoolMean, ilArrayShape, ilType) -> failwith "Instruction I_ldelema unsupported"(* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *)
+ | I_ldelem_any (ilArrayShap, ilType) -> failwith "Instruction I_ldelem_any unsupported" (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *)
+ | I_stelem_any (ilArrayShape, ilType) -> failwith "Instruction I_stelem_any unsupported" (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *)
+ | I_newarr (ilArrayShape, ilType) -> failwith "Instruction I_newarr unsupported" (* ILArrayShape = ILArrayShape.SingleDimensional for single dimensional arrays *)
+ | I_ldlen -> failwith "Instruction I_ldlen unsupported"
+
+ // "System.TypedReference" related instructions: almost
+ // no languages produce these, though they do occur in mscorlib.dll
+ // System.TypedReference represents a pair of a type and a byref-pointer
+ // to a value of that type.
+ | I_mkrefany (ilType) ->
+ stack.Push ilType // seems wrong
+ NoResult
+ | I_refanytype -> failwith "Instruction I_refanytype unsupported"
+ | I_refanyval (ilType) -> failwith "Instruction I_refanyval unsupported"
+
+ // Debug-specific
+ // I_seqpoint is a fake instruction to represent a sequence point:
+ // the next instruction starts the execution of the
+ // statement covered by the given range - this is a
+ // dummy instruction and is not emitted
+ | I_break -> failwith "Instruction I_break unsupported"
+ | I_seqpoint ilSourceMarker -> failwith "Instruction I_seqpoint unsupported"
+
+ // Varargs - C++ only
+ | I_arglist -> failwith "Instruction I_arglist unsupported"
+
+ // Local aggregates, i.e. stack allocated data (alloca) : C++ only
+ | I_localloc -> failwith "Instruction I_localloc unsupported"
+ | I_cpblk (ilAlignment, ilVolatility) -> failwith "Instruction I_cpblk unsupported"
+ | I_initblk (ilAlignment, ilVolatility) -> failwith "Instruction I_initblk unsupported"
+
+ // EXTENSIONS, e.g. MS-ILX
+ | EI_ilzero (ilType) -> failwith "Instruction EI_ilzero unsupported"
+ | EI_ldlen_multi (x, y) -> failwith "Instruction EI_ldlen_multi unsupported"
+ | I_other (ilxExtensionInstr) -> failwith "Instruction I_other unsupported"
+ let rec matchLabel label code =
+ match code with
+ | ILBasicBlock ilBasicBlock -> ilBasicBlock.Label = label
+ | GroupBlock (ilDebugMappings, ilCodes) -> ilCodes |> List.exists (fun x -> matchLabel label x)
+ | RestrictBlock (ilCodeLabels, ilCode) -> matchLabel label ilCode || ilCodeLabels |> List.exists (fun x -> x = label)
+ | TryBlock (ilCode, ilExceptionBlock) -> matchLabel label ilCode
+ let rec execCodeBlock code =
+ match code with
+ | ILBasicBlock ilBasicBlock ->
+ let rec loop index =
+ let instr = ilBasicBlock.Instructions.[index]
+ let result = execILBlock instr
+ let nextIndex = index + 1
+ match result with
+ | Return _ -> result
+ | Branch _ -> result
+ | ExceptionThrown _ -> result
+ | NoResult ->
+ if ilBasicBlock.Instructions.Length = nextIndex then
+ result
+ else
+ loop nextIndex
+ loop 0
+ | GroupBlock (ilDebugMappings, ilCodes) ->
+ let firstBlock = List.head ilCodes
+ let result = execCodeBlock firstBlock
+ match result with
+ | Branch targetLabel ->
+ let targetBlock =
+ ilCodes |> List.find (fun code -> matchLabel targetLabel code)
+ execCodeBlock targetBlock
+ | _ -> result
+ | RestrictBlock (ilCodeLabels, ilCode) ->
+ execCodeBlock ilCode
+ | TryBlock (ilCode, ilExceptionBlock) ->
+ // TODO error handling :)
+ execCodeBlock ilCode
+ printfn "%s.%s %A" typeDef.Name methodDef.Name parameters
+ if methodDef.IsUnmanagedExport then
+ printfn "IsUnmanagedExport"
+ NoResult
+ elif methodDef.IsInternalCall then
+ let result = InternalCalls.execInternalCall methodDef parameters
+ stack.Push result
+ NoResult
+ else
+ execCodeBlock methodDef.MethodBody.Code
diff --git a/samples/crlish/clrish/InternalCalls.fs b/samples/crlish/clrish/InternalCalls.fs
new file mode 100644
index 0000000..d92aca9
--- /dev/null
+++ b/samples/crlish/clrish/InternalCalls.fs
@@ -0,0 +1,11 @@
+module InternalCalls
+open System
+open System.Threading
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+let execInternalCall (meth: ILMethodDef) (parameters: obj[]) =
+ match meth.Name with
+ | "_CompareExchange" ->
+ Interlocked.CompareExchange(ref parameters.[0], parameters.[1], parameters.[2])
+ | _ -> failwith "internal call not supported"
diff --git a/samples/crlish/clrish/Loader.fs b/samples/crlish/clrish/Loader.fs
new file mode 100644
index 0000000..b9b542a
--- /dev/null
+++ b/samples/crlish/clrish/Loader.fs
@@ -0,0 +1,30 @@
+module Loader
+
+open System
+open System.Collections.Generic
+open System.IO
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+let assemblyPath = Environment.ExpandEnvironmentVariables(@"%windir%\Microsoft.NET\Framework\v4.0.30319")
+
+let modules = new Dictionary()
+
+let loadModuleFromPath path =
+ let ``module`` = OpenILModuleReader path defaults
+ match ``module``.ILModuleDef.Manifest with
+ | Some manifest ->
+ modules.Add(manifest.Name, ``module``)
+ | None -> failwith "Module has no manifest, only full assemblies are support"
+ ``module``
+
+let getModule (assemblyRef: ILAssemblyRef) =
+ if modules.ContainsKey assemblyRef.Name then
+ modules.[assemblyRef.Name]
+ else
+ // sooner or later we'll need to search more places/file type, but this will get the frawework .dlls
+ loadModuleFromPath (Path.Combine(assemblyPath, assemblyRef.Name + ".dll"))
+
+let closeModules() =
+ for ``module`` in modules.Values do
+ CloseILModuleReader ``module``
diff --git a/samples/crlish/clrish/MemoryManagement.fs b/samples/crlish/clrish/MemoryManagement.fs
new file mode 100644
index 0000000..f267de4
--- /dev/null
+++ b/samples/crlish/clrish/MemoryManagement.fs
@@ -0,0 +1,108 @@
+module MemoryManagement
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+let memoryChunkSize = 5120
+let memoryArrays: obj[][] = Array.zeroCreate memoryChunkSize
+
+let getSlotIndexes i =
+ let chunkIndex = i / memoryChunkSize
+ let index = i - (chunkIndex * memoryChunkSize)
+ chunkIndex, index
+
+let getSlotValue i =
+ let chunkIndex, index = getSlotIndexes i
+ memoryArrays.[chunkIndex].[index]
+
+let setSlotValue i value =
+ let chunkIndex, index = getSlotIndexes i
+ if memoryArrays.[chunkIndex] = null then
+ memoryArrays.[chunkIndex] <- Array.zeroCreate memoryChunkSize
+ memoryArrays.[chunkIndex].[index] <- value
+
+
+let heapPointer = ref (5 * memoryChunkSize)
+let threadStackPointer = ref 1
+
+let pushThreadParameters (parameters: obj[]) (targetMethod: ILMethodDef) =
+ for parameter in parameters do
+ setSlotValue !threadStackPointer parameter
+ incr threadStackPointer
+ setSlotValue !threadStackPointer (targetMethod, parameters.Length)
+ incr threadStackPointer
+
+let popThreadParameters () =
+ decr threadStackPointer
+ let _, parameterCount = (getSlotValue !threadStackPointer) :?> (ILMethodDef * int)
+ threadStackPointer := !threadStackPointer - parameterCount
+
+let getParameterAddress i =
+ let methodDesLocaction = !threadStackPointer - 1
+ let _, parameterCount = (getSlotValue methodDesLocaction) :?> (ILMethodDef * int)
+ !threadStackPointer - (parameterCount + 1) + i
+
+let staticFieldLocations = new Dictionary()
+
+let rec getDefaultValue (t: ILType) =
+ match t with
+ | ILType.Void -> failwith "Unsupported type"
+ | ILType.Array (_) -> null
+ | ILType.Value (ilTypeSpec) -> Activator.CreateInstance(Type.GetType(ilTypeSpec.TypeRef.QualifiedName))
+ | ILType.Boxed (ilTypeSpec) -> null
+ | ILType.Ptr (ilType) -> IntPtr.Zero :> obj
+ | ILType.Byref (ilType) -> failwith "Unsupported type"
+ | ILType.FunctionPointer (ilCallingSignature) -> failwith "Unsupported type"
+ | ILType.TypeVar i -> failwith "Unsupported type"
+ | ILType.Modified (required, ilTypeRef, ilType) -> getDefaultValue ilType
+
+let getFieldStaticFieldOffset t name =
+ t.Fields.AsList
+ |> List.filter (fun x -> x.IsStatic)
+ |> List.findIndex(fun x -> x.Name = name)
+
+let getStaticFieldAddress (tModule: ILModuleReader) (t: ILTypeDef) (field: ILFieldSpec) (execMethod: (ILMethodDef -> 'a)) =
+ // TODO this is will not provide a key that's unique for each type
+ let typeFullname = sprintf "%s, %s" t.Name tModule.ILModuleDef.Name
+
+ if not (staticFieldLocations.ContainsKey typeFullname) then
+ staticFieldLocations.Add(typeFullname, !heapPointer)
+ for field in t.Fields.AsList |> List.filter (fun x -> x.IsStatic) do
+ setSlotValue !heapPointer (getDefaultValue field.Type)
+ incr heapPointer
+
+ let staticCtor = t.Methods.AsList |> List.find (fun x -> x.IsClassInitializer)
+ execMethod staticCtor |> ignore
+
+ staticFieldLocations.[typeFullname] + (getFieldStaticFieldOffset t field.Name)
+
+let getStaticField (tModule: ILModuleReader) (t: ILTypeDef) (field: ILFieldSpec) (execMethod: (ILMethodDef -> 'a)) =
+ let location = getStaticFieldAddress tModule t field execMethod
+ getSlotValue location
+
+
+let getFieldInstranceFieldOffset t name =
+ t.Fields.AsList
+ |> List.filter (fun x -> not x.IsStatic)
+ |> List.findIndex(fun x -> x.Name = name)
+
+let getBlankObject (t: ILTypeDef) =
+ let objRef = !heapPointer
+ setSlotValue (!heapPointer) t
+ incr heapPointer
+ for field in t.Fields.AsList |> List.filter (fun x -> not x.IsStatic) do
+ setSlotValue !heapPointer (getDefaultValue field.Type)
+ incr heapPointer
+ objRef
+
+let storeValueInObjectField objRef value (currentModule: ILModuleReader) (fieldSpec: ILFieldSpec) =
+ let t, _ = TypeManagement.getType currentModule fieldSpec.EnclosingType.TypeSpec
+ let offset = getFieldInstranceFieldOffset t fieldSpec.Name
+ setSlotValue (objRef + offset) value
+
+let storeBoxedValue (value: obj) =
+ let objRef = !heapPointer
+ setSlotValue !heapPointer value
+ incr heapPointer
+ objRef
diff --git a/samples/crlish/clrish/Program.fs b/samples/crlish/clrish/Program.fs
new file mode 100644
index 0000000..f10a000
--- /dev/null
+++ b/samples/crlish/clrish/Program.fs
@@ -0,0 +1,19 @@
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+[]
+let main argv =
+ let entryModule = Loader.loadModuleFromPath argv.[0]
+ try
+ let entryPoint =
+ entryModule.ILModuleDef.TypeDefs |> Seq.collect (fun x -> x.Methods |> Seq.map (fun m -> x, m) ) |> Seq.tryFind (fun (t,m) -> m.IsEntryPoint)
+ match entryPoint with
+ | Some (t, entryPoint) ->
+ ExecutionEngine.exeMethod entryModule [||] t entryPoint |> ignore
+ | None -> failwith "No entry point found"
+ finally
+ Loader.closeModules()
+ 0
+
diff --git a/samples/crlish/clrish/TypeManagement.fs b/samples/crlish/clrish/TypeManagement.fs
new file mode 100644
index 0000000..27a935b
--- /dev/null
+++ b/samples/crlish/clrish/TypeManagement.fs
@@ -0,0 +1,21 @@
+module TypeManagement
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
+open Microsoft.FSharp.Compiler.AbstractIL.IL
+
+let getType (currentModule: ILModuleReader) (ilTypeSpec: ILTypeSpec) =
+ let typesModule =
+ if ilTypeSpec.Scope.IsLocalRef then
+ currentModule
+ else
+ Loader.getModule ilTypeSpec.Scope.AssemblyRef
+ let targetType =
+ typesModule.ILModuleDef.TypeDefs
+ |> Seq.append ( typesModule.ILModuleDef.TypeDefs |> Seq.collect(fun x -> x.NestedTypes))
+ |> Seq.tryFind (fun x -> x.Name = ilTypeSpec.Name)
+ match targetType with
+ | Some x -> x, typesModule
+ | None -> failwithf "Failed to load %A" ilTypeSpec
+
+
diff --git a/samples/crlish/clrish/crlish.fsproj b/samples/crlish/clrish/crlish.fsproj
new file mode 100644
index 0000000..d23ed60
--- /dev/null
+++ b/samples/crlish/clrish/crlish.fsproj
@@ -0,0 +1,75 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ 0898e907-dab0-49fe-9f9a-5767d80d2376
+ Exe
+ crlish
+ crlish
+ v4.5
+ crlish
+
+
+ true
+ full
+ false
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ 3
+ AnyCPU
+ bin\Debug\crlish.XML
+ true
+ "C:\code\clrish\src\TestApp\bin\Debug\TestApp.exe"
+
+
+ pdbonly
+ true
+ true
+ bin\Release\
+ TRACE
+ 3
+ AnyCPU
+ bin\Release\crlish.XML
+ true
+
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ FSharp.AbsIL
+ {2e4d67b4-522d-4cf7-97e4-ba940f0b18f3}
+ True
+
+
+
+ 11
+
+
+
+
\ No newline at end of file
diff --git a/src/absil-vs2012.sln b/src/absil-vs2012.sln
new file mode 100644
index 0000000..87ef28c
--- /dev/null
+++ b/src/absil-vs2012.sln
@@ -0,0 +1,63 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.AbsIL", "fsharp\FSharp.AbsIL\FSharp.AbsIL.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "..\samples\crlish\TestApp\TestApp.csproj", "{E3F21F5E-94A5-485D-9FC0-571D27E87EE8}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "crlish", "..\samples\crlish\clrish\crlish.fsproj", "{0898E907-DAB0-49FE-9F9A-5767D80D2376}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{A3F6BF8D-E804-4804-B39D-CC1704B98A2F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "clrish", "clrish", "{E7297A96-1B40-4790-9D27-DEAEE95E7633}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|Mixed Platforms = Debug|Mixed Platforms
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.ActiveCfg = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|x86.Build.0 = Debug|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Mixed Platforms.Build.0 = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.ActiveCfg = Release|x86
+ {2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|x86.Build.0 = Release|x86
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8}.Release|x86.ActiveCfg = Release|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376}.Release|x86.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {E7297A96-1B40-4790-9D27-DEAEE95E7633} = {A3F6BF8D-E804-4804-B39D-CC1704B98A2F}
+ {E3F21F5E-94A5-485D-9FC0-571D27E87EE8} = {E7297A96-1B40-4790-9D27-DEAEE95E7633}
+ {0898E907-DAB0-49FE-9F9A-5767D80D2376} = {E7297A96-1B40-4790-9D27-DEAEE95E7633}
+ EndGlobalSection
+EndGlobal
diff --git a/src/absil/bytes.fs b/src/absil/bytes.fs
new file mode 100644
index 0000000..2447a0d
--- /dev/null
+++ b/src/absil/bytes.fs
@@ -0,0 +1,146 @@
+//----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
+
+/// Byte arrays
+namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
+
+open System.IO
+open Internal.Utilities
+
+open Microsoft.FSharp.Compiler.AbstractIL
+open Microsoft.FSharp.Compiler.AbstractIL.Internal
+
+module internal Bytes =
+ let b0 n = (n &&& 0xFF)
+ let b1 n = ((n >>> 8) &&& 0xFF)
+ let b2 n = ((n >>> 16) &&& 0xFF)
+ let b3 n = ((n >>> 24) &&& 0xFF)
+
+ let dWw1 n = int32 ((n >>> 32) &&& 0xFFFFFFFFL)
+ let dWw0 n = int32 (n &&& 0xFFFFFFFFL)
+
+ let get (b:byte[]) n = int32 (Array.get b n)
+ let zeroCreate n : byte[] = Array.zeroCreate n
+
+ let sub ( b:byte[]) s l = Array.sub b s l
+ let blit (a:byte[]) b c d e = Array.blit a b c d e
+
+ let ofInt32Array (arr:int[]) = Array.init arr.Length (fun i -> byte arr.[i])
+
+ let stringAsUtf8NullTerminated (s:string) =
+ Array.append (System.Text.Encoding.UTF8.GetBytes s) (ofInt32Array [| 0x0 |])
+
+ let stringAsUnicodeNullTerminated (s:string) =
+ Array.append (System.Text.Encoding.Unicode.GetBytes s) (ofInt32Array [| 0x0;0x0 |])
+
+type internal ByteStream =
+ { bytes: byte[];
+ mutable pos: int;
+ max: int }
+ member b.ReadByte() =
+ if b.pos >= b.max then failwith "end of stream";
+ let res = b.bytes.[b.pos]
+ b.pos <- b.pos + 1;
+ res
+ member b.ReadUtf8String n =
+ let res = System.Text.Encoding.UTF8.GetString(b.bytes,b.pos,n)
+ b.pos <- b.pos + n; res
+
+ static member FromBytes (b:byte[],n,len) =
+ if n < 0 || (n+len) > b.Length then failwith "FromBytes";
+ { bytes = b; pos = n; max = n+len }
+
+ member b.ReadBytes n =
+ if b.pos + n > b.max then failwith "ReadBytes: end of stream";
+ let res = Bytes.sub b.bytes b.pos n
+ b.pos <- b.pos + n;
+ res
+
+ member b.Position = b.pos
+#if LAZY_UNPICKLE
+ member b.CloneAndSeek = { bytes=b.bytes; pos=pos; max=b.max }
+ member b.Skip = b.pos <- b.pos + n
+#endif
+
+
+type internal ByteBuffer =
+ { mutable bbArray: byte[];
+ mutable bbCurrent: int }
+
+ member buf.Ensure newSize =
+ let oldBufSize = buf.bbArray.Length
+ if newSize > oldBufSize then
+ let old = buf.bbArray
+ buf.bbArray <- Bytes.zeroCreate (max newSize (oldBufSize * 2));
+ Bytes.blit old 0 buf.bbArray 0 buf.bbCurrent;
+
+ member buf.Close () = Bytes.sub buf.bbArray 0 buf.bbCurrent
+
+ member buf.EmitIntAsByte (i:int) =
+ let newSize = buf.bbCurrent + 1
+ buf.Ensure newSize;
+ buf.bbArray.[buf.bbCurrent] <- byte i
+ buf.bbCurrent <- newSize
+
+ member buf.EmitByte (b:byte) = buf.EmitIntAsByte (int b)
+
+ member buf.EmitIntsAsBytes (arr:int[]) =
+ let n = arr.Length
+ let newSize = buf.bbCurrent + n
+ buf.Ensure newSize;
+ let bbarr = buf.bbArray
+ let bbbase = buf.bbCurrent
+ for i = 0 to n - 1 do
+ bbarr.[bbbase + i] <- byte arr.[i]
+ buf.bbCurrent <- newSize
+
+ member bb.FixupInt32 pos n =
+ bb.bbArray.[pos] <- (Bytes.b0 n |> byte);
+ bb.bbArray.[pos + 1] <- (Bytes.b1 n |> byte);
+ bb.bbArray.[pos + 2] <- (Bytes.b2 n |> byte);
+ bb.bbArray.[pos + 3] <- (Bytes.b3 n |> byte);
+
+ member buf.EmitInt32 n =
+ let newSize = buf.bbCurrent + 4
+ buf.Ensure newSize;
+ buf.FixupInt32 buf.bbCurrent n;
+ buf.bbCurrent <- newSize
+
+ member buf.EmitBytes (i:byte[]) =
+ let n = i.Length
+ let newSize = buf.bbCurrent + n
+ buf.Ensure newSize;
+ Bytes.blit i 0 buf.bbArray buf.bbCurrent n;
+ buf.bbCurrent <- newSize
+
+ member buf.EmitInt32AsUInt16 n =
+ let newSize = buf.bbCurrent + 2
+ buf.Ensure newSize;
+ buf.bbArray.[buf.bbCurrent] <- (Bytes.b0 n |> byte);
+ buf.bbArray.[buf.bbCurrent + 1] <- (Bytes.b1 n |> byte);
+ buf.bbCurrent <- newSize
+
+ member buf.EmitBoolAsByte (b:bool) = buf.EmitIntAsByte (if b then 1 else 0)
+
+ member buf.EmitUInt16 (x:uint16) = buf.EmitInt32AsUInt16 (int32 x)
+
+ member buf.EmitInt64 x =
+ buf.EmitInt32 (Bytes.dWw0 x);
+ buf.EmitInt32 (Bytes.dWw1 x)
+
+ member buf.Position = buf.bbCurrent
+
+ static member Create sz =
+ { bbArray=Bytes.zeroCreate sz;
+ bbCurrent = 0; }
+
+
diff --git a/src/absil/bytes.fsi b/src/absil/bytes.fsi
new file mode 100644
index 0000000..113e124
--- /dev/null
+++ b/src/absil/bytes.fsi
@@ -0,0 +1,66 @@
+//----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
+
+
+/// Blobs of bytes, cross-compiling
+namespace Microsoft.FSharp.Compiler.AbstractIL.Internal
+
+open Internal.Utilities
+
+open Microsoft.FSharp.Compiler.AbstractIL
+open Microsoft.FSharp.Compiler.AbstractIL.Internal
+
+
+module internal Bytes =
+ /// returned int will be 0 <= x <= 255
+ val get: byte[] -> int -> int
+ val zeroCreate: int -> byte[]
+ /// each int must be 0 <= x <= 255
+ val ofInt32Array: int[] -> byte[]
+ /// each int will be 0 <= x <= 255
+
+ val blit: byte[] -> int -> byte[] -> int -> int -> unit
+
+ val stringAsUnicodeNullTerminated: string -> byte[]
+ val stringAsUtf8NullTerminated: string -> byte[]
+
+
+/// Imperative buffers and streams of byte[]
+[]
+type internal ByteBuffer =
+ member Close : unit -> byte[]
+ member EmitIntAsByte : int -> unit
+ member EmitIntsAsBytes : int[] -> unit
+ member EmitByte : byte -> unit
+ member EmitBytes : byte[] -> unit
+ member EmitInt32 : int32 -> unit
+ member EmitInt64 : int64 -> unit
+ member FixupInt32 : pos: int -> value: int32 -> unit
+ member EmitInt32AsUInt16 : int32 -> unit
+ member EmitBoolAsByte : bool -> unit
+ member EmitUInt16 : uint16 -> unit
+ member Position : int
+ static member Create : int -> ByteBuffer
+
+
+[]
+type internal ByteStream =
+ member ReadByte : unit -> byte
+ member ReadBytes : int -> byte[]
+ member ReadUtf8String : int -> string
+ member Position : int
+ static member FromBytes : byte[] * start:int * length:int -> ByteStream
+
+#if LAZY_UNPICKLE
+ member CloneAndSeek : int -> ByteStream
+ member Skip : int -> unit
+#endif
diff --git a/src/absil/il.fs b/src/absil/il.fs
new file mode 100644
index 0000000..6da501d
--- /dev/null
+++ b/src/absil/il.fs
@@ -0,0 +1,5026 @@
+//----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2012 Microsoft Corporation.
+//
+// This source code is subject to terms and conditions of the Apache License, Version 2.0. A
+// copy of the license can be found in the License.html file at the root of this distribution.
+// By using this source code in any fashion, you are agreeing to be bound
+// by the terms of the Apache License, Version 2.0.
+//
+// You must not remove this notice, or any other, from this software.
+//----------------------------------------------------------------------------
+
+module Microsoft.FSharp.Compiler.AbstractIL.IL
+
+#nowarn "49"
+#nowarn "343" // The type 'ILAssemblyRef' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'.
+#nowarn "346" // The struct, record or union type 'IlxExtensionType' has an explicit implementation of 'Object.Equals'. ...
+
+
+open Internal.Utilities
+open Microsoft.FSharp.Compiler.AbstractIL
+open Microsoft.FSharp.Compiler.AbstractIL.Internal
+open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
+open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
+open System.Collections.Generic
+open System.Collections
+
+let logging = false
+
+// Officially supported way to detect if we are running on Mono.
+// See http://www.mono-project.com/FAQ:_Technical
+// "How can I detect if am running in Mono?" section
+let runningOnMono =
+ try
+ System.Type.GetType("Mono.Runtime") <> null
+ with e->
+ // Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent
+ // that is not reliable.
+ // This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is
+ // called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get
+ // their issue fixed but we need to be robust here anyway.
+ false
+
+let _ = if logging then dprintn "* warning: Il.logging is on"
+
+let isNil x = match x with [] -> true | _ -> false
+let nonNil x = match x with [] -> false | _ -> true
+let int_order = LanguagePrimitives.FastGenericComparer
+
+let notlazy v = Lazy.CreateFromValue v
+
+/// A little ugly, but the idea is that if a data structure does not
+/// contain lazy values then we don't add laziness. So if the thing to map
+/// is already evaluated then immediately apply the function.
+let lazyMap f (x:Lazy<_>) =
+ if x.IsValueCreated then notlazy (f (x.Force())) else lazy (f (x.Force()))
+
+// --------------------------------------------------------------------
+// Utilities: type names
+// --------------------------------------------------------------------
+
+let splitNameAt (nm:string) idx =
+ if idx < 0 then failwith "splitNameAt: idx < 0";
+ let last = nm.Length - 1
+ if idx > last then failwith "splitNameAt: idx > last";
+ (nm.Substring(0,idx)),
+ (if idx < last then nm.Substring (idx+1,last - idx) else "")
+
+let rec splitNamespaceAux (nm:string) =
+ match nm.IndexOf '.' with
+ | -1 -> [nm]
+ | idx ->
+ let s1,s2 = splitNameAt nm idx
+ s1::splitNamespaceAux s2
+
+/// Global State. All namespace splits ever seen
+// ++GLOBAL MUTABLE STATE
+let memoizeNamespaceTable = new Dictionary(10)
+
+// ++GLOBAL MUTABLE STATE
+let memoizeNamespaceRightTable = new Dictionary(100)
+
+
+let splitNamespace nm =
+ let mutable res = Unchecked.defaultof<_>
+ let ok = memoizeNamespaceTable.TryGetValue(nm,&res)
+ if ok then res else
+ let x = splitNamespaceAux nm
+ (memoizeNamespaceTable.[nm] <- x; x)
+
+let splitNamespaceMemoized nm = splitNamespace nm
+
+// ++GLOBAL MUTABLE STATE
+let memoizeNamespaceArrayTable =
+ Dictionary(10)
+
+let splitNamespaceToArray nm =
+ let mutable res = Unchecked.defaultof<_>
+ let ok = memoizeNamespaceArrayTable.TryGetValue(nm,&res)
+ if ok then res else
+ let x = Array.ofList (splitNamespace nm)
+ (memoizeNamespaceArrayTable.[nm] <- x; x)
+
+
+let splitILTypeName (nm:string) =
+ match nm.LastIndexOf '.' with
+ | -1 -> [],nm
+ | idx ->
+ let s1,s2 = splitNameAt nm idx
+ splitNamespace s1,s2
+
+let emptyStringArray = ([| |] : string[])
+
+// Duplciate of comment in import.fs:
+// The type names that flow to the point include the "mangled" type names used for static parameters for provided types.
+// For example,
+// Foo.Bar,"1.0"
+// This is because the ImportSystemType code goes via Abstract IL type references. Ultimately this probably isn't
+// the best way to do things.
+let splitILTypeNameWithPossibleStaticArguments (nm:string) =
+ let nm,suffix =
+ match nm.IndexOf ',' with
+ | -1 -> nm, None
+ | idx -> let s1, s2 = splitNameAt nm idx in s1, Some s2
+
+ let nsp,nm =
+ match nm.LastIndexOf '.' with
+ | -1 -> emptyStringArray,nm
+ | idx ->
+ let s1,s2 = splitNameAt nm idx
+ splitNamespaceToArray s1,s2
+ nsp, (match suffix with None -> nm | Some s -> nm + "," + s)
+
+(*
+splitILTypeNameWithPossibleStaticArguments "Foo" = ([| |], "Foo")
+splitILTypeNameWithPossibleStaticArguments "Foo.Bar" = ([| "Foo" |], "Bar")
+splitILTypeNameWithPossibleStaticArguments "Foo.Bar,3" = ([| "Foo" |], "Bar,3")
+splitILTypeNameWithPossibleStaticArguments "Foo.Bar," = ([| "Foo" |], "Bar,")
+splitILTypeNameWithPossibleStaticArguments "Foo.Bar,\"1.0\"" = ([| "Foo" |], "Bar,\"1.0\"")
+splitILTypeNameWithPossibleStaticArguments "Foo.Bar.Bar,\"1.0\"" = ([| "Foo"; "Bar" |], "Bar,\"1.0\"")
+*)
+
+let unsplitTypeName (ns,n) =
+ match ns with
+ | [] -> String.concat "." ns + "." + n
+ | _ -> n
+
+let splitTypeNameRightAux nm =
+ if String.contains nm '.' then
+ let idx = String.rindex nm '.'
+ let s1,s2 = splitNameAt nm idx
+ Some s1,s2
+ else None, nm
+
+let splitTypeNameRight nm =
+ let mutable res = Unchecked.defaultof<_>
+ let ok = memoizeNamespaceRightTable.TryGetValue(nm,&res)
+ if ok then res else
+ let x = splitTypeNameRightAux nm
+ (memoizeNamespaceRightTable.[nm] <- x; x)
+
+// --------------------------------------------------------------------
+// Ordered lists with a lookup table
+// --------------------------------------------------------------------
+
+/// This is used to store event, property and field maps.
+///
+/// Review: this is not such a great data structure.
+type LazyOrderedMultiMap<'Key,'Data when 'Key : equality>(keyf : 'Data -> 'Key, lazyItems : Lazy<'Data list>) =
+
+ let quickMap=
+ lazyItems |> lazyMap (fun entries ->
+ let t = new Dictionary<_,_>(entries.Length, HashIdentity.Structural)
+ do entries |> List.iter (fun y -> let key = keyf y in t.[key] <- y :: (if t.ContainsKey(key) then t.[key] else []))
+ t)
+
+ member self.Entries() = lazyItems.Force()
+
+ member self.Add(y) = new LazyOrderedMultiMap<'Key,'Data>(keyf, lazyItems |> lazyMap (fun x -> y :: x))
+
+ member self.Filter(f) = new LazyOrderedMultiMap<'Key,'Data>(keyf, lazyItems |> lazyMap (List.filter f))
+
+ member self.Item with get(x) = let t = quickMap.Force() in if t.ContainsKey x then t.[x] else []
+
+
+//---------------------------------------------------------------------
+// SHA1 hash-signing algorithm. Used to get the public key token from
+// the public key.
+//---------------------------------------------------------------------
+
+
+let b0 n = (n &&& 0xFF)
+let b1 n = ((n >>> 8) &&& 0xFF)
+let b2 n = ((n >>> 16) &&& 0xFF)
+let b3 n = ((n >>> 24) &&& 0xFF)
+
+
+module SHA1 =
+ let inline (>>>&) (x:int) (y:int) = int32 (uint32 x >>> y)
+ let f(t,b,c,d) =
+ if t < 20 then (b &&& c) ||| ((~~~b) &&& d) else
+ if t < 40 then b ^^^ c ^^^ d else
+ if t < 60 then (b &&& c) ||| (b &&& d) ||| (c &&& d) else
+ b ^^^ c ^^^ d
+
+ let k0to19 = 0x5A827999
+ let k20to39 = 0x6ED9EBA1
+ let k40to59 = 0x8F1BBCDC
+ let k60to79 = 0xCA62C1D6
+
+ let k t =
+ if t < 20 then k0to19
+ elif t < 40 then k20to39
+ elif t < 60 then k40to59
+ else k60to79
+
+
+ type chan = SHABytes of byte[]
+ type sha_instream =
+ { stream: chan;
+ mutable pos: int;
+ mutable eof: bool; }
+
+ let rot_left32 x n = (x <<< n) ||| (x >>>& (32-n))
+
+ let sha_eof sha = sha.eof
+
+ (* padding and length (in bits!) recorded at end *)
+ let sha_after_eof sha =
+ let n = sha.pos
+ let len =
+ (match sha.stream with
+ | SHABytes s -> s.Length)
+ if n = len then 0x80
+ else
+ let padded_len = (((len + 9 + 63) / 64) * 64) - 8
+ if n < padded_len - 8 then 0x0
+ elif (n &&& 63) = 56 then int32 ((int64 len * int64 8) >>> 56) &&& 0xff
+ elif (n &&& 63) = 57 then int32 ((int64 len * int64 8) >>> 48) &&& 0xff
+ elif (n &&& 63) = 58 then int32 ((int64 len * int64 8) >>> 40) &&& 0xff
+ elif (n &&& 63) = 59 then int32 ((int64 len * int64 8) >>> 32) &&& 0xff
+ elif (n &&& 63) = 60 then int32 ((int64 len * int64 8) >>> 24) &&& 0xff
+ elif (n &&& 63) = 61 then int32 ((int64 len * int64 8) >>> 16) &&& 0xff
+ elif (n &&& 63) = 62 then int32 ((int64 len * int64 8) >>> 8) &&& 0xff
+ elif (n &&& 63) = 63 then (sha.eof <- true; int32 (int64 len * int64 8) &&& 0xff)
+ else 0x0
+
+ let sha_read8 sha =
+ let b =
+ match sha.stream with
+ | SHABytes s -> if sha.pos >= s.Length then sha_after_eof sha else int32 s.[sha.pos]
+ sha.pos <- sha.pos + 1;
+ b
+
+ let sha_read32 sha =
+ let b0 = sha_read8 sha
+ let b1 = sha_read8 sha
+ let b2 = sha_read8 sha
+ let b3 = sha_read8 sha
+ let res = (b0 <<< 24) ||| (b1 <<< 16) ||| (b2 <<< 8) ||| b3
+ res
+
+
+ let sha1_hash sha =
+ let h0 = ref 0x67452301
+ let h1 = ref 0xEFCDAB89
+ let h2 = ref 0x98BADCFE
+ let h3 = ref 0x10325476
+ let h4 = ref 0xC3D2E1F0
+ let a = ref 0
+ let b = ref 0
+ let c = ref 0
+ let d = ref 0
+ let e = ref 0
+ let w = Array.create 80 0x00
+ while (not (sha_eof sha)) do
+ for i = 0 to 15 do
+ w.[i] <- sha_read32 sha
+ for t = 16 to 79 do
+ w.[t] <- rot_left32 (w.[t-3] ^^^ w.[t-8] ^^^ w.[t-14] ^^^ w.[t-16]) 1;
+ a := !h0;
+ b := !h1;
+ c := !h2;
+ d := !h3;
+ e := !h4;
+ for t = 0 to 79 do
+ let temp = (rot_left32 !a 5) + f(t,!b,!c,!d) + !e + w.[t] + k(t)
+ e := !d;
+ d := !c;
+ c := rot_left32 !b 30;
+ b := !a;
+ a := temp;
+ h0 := !h0 + !a;
+ h1 := !h1 + !b;
+ h2 := !h2 + !c;
+ h3 := !h3 + !d;
+ h4 := !h4 + !e
+ done;
+ (!h0,!h1,!h2,!h3,!h4)
+
+ let sha1HashBytes s =
+ let (_h0,_h1,_h2,h3,h4) = sha1_hash { stream = SHABytes s; pos = 0; eof = false } // the result of the SHA algorithm is stored in registers 3 and 4
+ Array.map byte [| b0 h4; b1 h4; b2 h4; b3 h4; b0 h3; b1 h3; b2 h3; b3 h3; |]
+
+
+let sha1HashBytes s = SHA1.sha1HashBytes s
+
+// --------------------------------------------------------------------
+// ILList
+// --------------------------------------------------------------------
+
+/// ILList is the type used to store relatively small lists in the Abstract IL data structures,
+/// i.e. for ILTypes, ILGenericArgs, ILParameters and ILLocals.
+
+// This #if starts isolating the representation for "ILTypes", "ILGenericArgs", "ILParameters" and "ILLocals"
+// with the aim of making it possible to easily switch between using arrays and lists as representations for these.
+// THis is because many allocations of these small lists appear in memory logs.
+//
+// The "obviouos" step is to use arrays instead of lists. However, this is routinely and surprisingly disappointing.
+// As a result, we haven’t enabled the use of arrays: we had expected this change to give a perf gain,
+// but it does not! It even gives a small perf loss. We've tried this approach on several other occasions
+// for other data structures and each time been surprised that there’s no perf gain. It's possible that
+// arrays-of-references are just not as fast as we expect here: either the runtime check on assignment
+// into the array, or some kind of write barrier may be degrading performance.
+//
+// However, There must surely be some better data structure here than allocating endless linked-list containing one item
+// each. One option is to use a linked-list structure that stores multiple elements in each allocation, e.g.
+//
+// type ThreeList<'T> = T of 'T * 'T * 'T * ThreeList<'T>
+//
+// and a similar hack is used as the underlying representation fot List<'T>, where we store a "constant" value to indicate the end
+// of the sequence. Some of the 'T values would be empty to indicate a partially-filled node. Storing an integer would of course
+// make things clearer, and allow values-with-null to be stored in the data structure:
+//
+// type ThreeList<'T> = T of int * 'T * 'T * 'T * ThreeList<'T>
+//
+// Since we haven't quite given up on moving away from lists as yet, the #if below still feels useful
+// as it isolates the representation of these data structures from the rest of the compiler.
+//
+// Note this is similar to the use of "Flat Lists" in the tast.fs data structures where we tried to eliminate
+// the use of lists in the tast.fs nodes of the compiler, but that also didn't give perf gains.
+//
+// If it turns out that we just eventually completely abandon these exercises then we can eliminate this code and
+// universally replace "ILList" and "FlatList" by "List".
+
+#if ABSIL_USES_ARRAY_FOR_ILLIST
+type ILList<'T> = 'T[]
+[]
+module ILList =
+ let inline map f x = Array.map f x
+ let inline mapi f x = Array.mapi f x
+ let inline isEmpty (x:ILList<_>) = x.Length <> 0
+ let inline toArray (x:ILList<_>) = x
+ let inline ofArray (x:'T[]) = x
+ let inline nth n (x:'T[]) = x.[n]
+ let inline toList (x:ILList<_>) = Array.toList x
+ let inline ofList (x:'T list) = Array.ofList x
+ let inline lengthsEqAndForall2 f x1 x2 = Array.lengthsEqAndForall2 f x1 x2
+ let inline init n f = Array.init n f
+ let inline empty<'T> = ([| |] :'T[])
+ let inline iter f (x:'T[]) = Array.iter f x
+ let inline iteri f (x:'T[]) = Array.iteri f x
+ let inline foldBack f (x:'T[]) z = Array.foldBack f x z
+ let inline exists f x = Array.exists f x
+#endif
+
+//#if ABSIL_USES_LIST_FOR_ILLIST
+type ILList<'T> = 'T list
+
+[]
+module ILList =
+ let inline map f x = List.map f x
+ let inline mapi f x = List.mapi f x
+ let inline isEmpty x = match x with [] -> true | _ -> false
+ let inline toArray (x:ILList<_>) = List.toArray x
+ let inline ofArray (x:'T[]) = List.ofArray x
+ let inline iter f (x:'T list) = List.iter f x
+ let inline iteri f (x:'T list) = List.iteri f x
+ let inline nth (x:'T list) n = List.nth x n
+ let inline toList (x:ILList<_>) = x
+ let inline ofList (x:'T list) = x
+ let inline lengthsEqAndForall2 f x1 x2 = List.lengthsEqAndForall2 f x1 x2
+ let inline init n f = List.init n f
+ let inline empty<'T> = ([ ] :'T list)
+ let inline foldBack f x z = List.foldBack f x z
+ let inline exists f x = List.exists f x
+//#endif // ABSIL_USES_LIST_FOR_ILLIST
+
+#if ABSIL_USES_THREELIST_FOR_ILLIST
+type ILList<'T> = ThreeList<'T>
+
+[]
+module ILList =
+ let inline map f x = ThreeList.map f x
+ let inline mapi f x = ThreeList.mapi f x
+ let inline isEmpty x = ThreeList.isEmpty x
+ let inline toArray (x:ILList<_>) = ThreeList.toArray x
+ let inline ofArray (x:'T[]) = ThreeList.ofArray x
+ let inline iter f (x:ILList<'T>) = ThreeList.iter f x
+ let inline iteri f (x:ILList<'T>) = ThreeList.iteri f x
+ let inline toList (x:ILList<_>) = ThreeList.toList x
+ let inline nth (x:ILList<'T>) n = ThreeList.nth x n
+ let inline ofList (x:'T list) = ThreeList.ofList x
+ let inline lengthsEqAndForall2 f x1 x2 = ThreeList.lengthsEqAndForall2 f x1 x2
+ let inline init n f = ThreeList.init n f
+ let inline empty<'T> = ThreeList.empty<'T>
+ let inline foldBack f x z = ThreeList.foldBack f x z
+ let inline exists f x = ThreeList.exists f x
+#endif
+
+// --------------------------------------------------------------------
+//
+// --------------------------------------------------------------------
+
+type ILVersionInfo = uint16 * uint16 * uint16 * uint16
+
+type Locale = string
+
+[]
+type PublicKey =
+ | PublicKey of byte[]
+ | PublicKeyToken of byte[]
+ member x.IsKey=match x with PublicKey _ -> true | _ -> false
+ member x.IsKeyToken=match x with PublicKeyToken _ -> true | _ -> false
+ member x.Key=match x with PublicKey b -> b | _ -> invalidOp "not a key"
+ member x.KeyToken=match x with PublicKeyToken b -> b | _ -> invalidOp"not a key token"
+
+ member x.ToToken() =
+ match x with
+ | PublicKey bytes -> SHA1.sha1HashBytes bytes
+ | PublicKeyToken token -> token
+ static member KeyAsToken(k) = PublicKeyToken(PublicKey(k).ToToken())
+
+[]
+type AssemblyRefData =
+ { assemRefName: string;
+ assemRefHash: byte[] option;
+ assemRefPublicKeyInfo: PublicKey option;
+ assemRefRetargetable: bool;
+ assemRefVersion: ILVersionInfo option;
+ assemRefLocale: Locale option; }
+
+/// Global state: table of all assembly references keyed by AssemblyRefData
+let AssemblyRefUniqueStampGenerator = new UniqueStampGenerator()
+
+[]
+type ILAssemblyRef(data) =
+ let uniqueStamp = AssemblyRefUniqueStampGenerator.Encode(data)
+ member x.Name=data.assemRefName
+ member x.Hash=data.assemRefHash
+ member x.PublicKey=data.assemRefPublicKeyInfo
+ member x.Retargetable=data.assemRefRetargetable
+ member x.Version=data.assemRefVersion
+ member x.Locale=data.assemRefLocale
+ member x.UniqueStamp=uniqueStamp
+ override x.GetHashCode() = uniqueStamp
+ override x.Equals(yobj) = ((yobj :?> ILAssemblyRef).UniqueStamp = uniqueStamp)
+ interface System.IComparable with
+ override x.CompareTo(yobj) = compare (yobj :?> ILAssemblyRef).UniqueStamp uniqueStamp
+ static member Create(name,hash,publicKey,retargetable,version,locale) =
+ ILAssemblyRef
+ { assemRefName=name;
+ assemRefHash=hash;
+ assemRefPublicKeyInfo=publicKey;
+ assemRefRetargetable=retargetable;
+ assemRefVersion=version;
+ assemRefLocale=locale; }
+
+ static member FromAssemblyName (aname:System.Reflection.AssemblyName) =
+ let culture = None
+ let locale = None
+ let version =
+ let v = aname.Version
+ Some(uint16 v.Major,uint16 v.Minor,uint16 v.Build,uint16 v.Revision)
+ let key =
+ match aname.GetPublicKeyToken() with
+ | null | [| |] -> None
+ | bytes -> Some (PublicKeyToken bytes)
+ let retargetable = (aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable)
+ ILAssemblyRef.Create(aname.Name,culture,key,retargetable,version,locale)
+
+
+ member aref.QualifiedName =
+ let b = new System.Text.StringBuilder(100)
+ let add (s:string) = (b.Append(s) |> ignore)
+ let addC (s:char) = (b.Append(s) |> ignore)
+ add(aref.Name);
+ match aref.Version with
+ | None -> ()
+ | Some (a,b,c,d) ->
+ add ", Version=";
+ add (string (int a))
+ add ".";
+ add (string (int b))
+ add ".";
+ add (string (int c))
+ add ".";
+ add (string (int d))
+ add ", Culture="
+ match aref.Locale with
+ | None -> add "neutral"
+ | Some b -> add b
+ add ", PublicKeyToken="
+ match aref.PublicKey with
+ | None -> add "null"
+ | Some pki ->
+ let pkt = pki.ToToken()
+ let convDigit(digit) =
+ let digitc =
+ if digit < 10
+ then System.Convert.ToInt32 '0' + digit
+ else System.Convert.ToInt32 'a' + (digit - 10)
+ System.Convert.ToChar(digitc)
+ for i = 0 to pkt.Length-1 do
+ let v = pkt.[i]
+ addC (convDigit(System.Convert.ToInt32(v)/16))
+ addC (convDigit(System.Convert.ToInt32(v)%16))
+ // retargetable can be true only for system assemblies that definitely have Version
+ if aref.Retargetable then
+ add ", Retargetable=Yes"
+ b.ToString()
+
+
+[]
+type ILModuleRef =
+ { name: string;
+ hasMetadata: bool;
+ hash: byte[] option; }
+ static member Create(name,hasMetadata,hash) =
+ { name=name;
+ hasMetadata= hasMetadata;
+ hash=hash }
+
+ member x.Name=x.name
+ member x.HasMetadata=x.hasMetadata
+ member x.Hash=x.hash
+
+[]
+[]
+type ILScopeRef =
+ | Local
+ | Module of ILModuleRef
+ | Assembly of ILAssemblyRef
+ member x.IsLocalRef = match x with ILScopeRef.Local -> true | _ -> false
+ member x.IsModuleRef = match x with ILScopeRef.Module _ -> true | _ -> false
+ member x.IsAssemblyRef= match x with ILScopeRef.Assembly _ -> true | _ -> false
+ member x.ModuleRef = match x with ILScopeRef.Module x -> x | _ -> failwith "not a module reference"
+ member x.AssemblyRef = match x with ILScopeRef.Assembly x -> x | _ -> failwith "not an assembly reference"
+
+ member scoref.QualifiedName =
+ match scoref with
+ | ILScopeRef.Local -> ""
+ | ILScopeRef.Module mref -> "module "^mref.Name
+ | ILScopeRef.Assembly aref when aref.Name = "mscorlib" -> ""
+ | ILScopeRef.Assembly aref -> aref.QualifiedName
+
+ member scoref.QualifiedNameWithNoShortMscorlib =
+ match scoref with
+ | ILScopeRef.Local -> ""
+ | ILScopeRef.Module mref -> "module "+mref.Name
+ | ILScopeRef.Assembly aref -> aref.QualifiedName
+
+type ILArrayBound = int32 option
+type ILArrayBounds = ILArrayBound * ILArrayBound
+
+[]
+type ILArrayShape =
+ | ILArrayShape of ILArrayBounds list (* lobound/size pairs *)
+ member x.Rank = (let (ILArrayShape l) = x in l.Length)
+ static member SingleDimensional = ILArrayShapeStatics.SingleDimensional
+ static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (Some 0,None))
+
+
+and ILArrayShapeStatics() =
+ static let singleDimensional = ILArrayShape [(Some 0, None)]
+ static member SingleDimensional = singleDimensional
+
+/// Calling conventions. These are used in method pointer types.
+[]
+type ILArgConvention =
+ | Default
+ | CDecl
+ | StdCall
+ | ThisCall
+ | FastCall
+ | VarArg
+
+[]
+type ILThisConvention =
+ | Instance
+ | InstanceExplicit
+ | Static
+
+[]
+type ILCallingConv =
+ | Callconv of ILThisConvention * ILArgConvention
+ member x.ThisConv = let (Callconv(a,_b)) = x in a
+ member x.BasicConv = let (Callconv(_a,b)) = x in b
+ member x.IsInstance = match x.ThisConv with ILThisConvention.Instance -> true | _ -> false
+ member x.IsInstanceExplicit = match x.ThisConv with ILThisConvention.InstanceExplicit -> true | _ -> false
+ member x.IsStatic = match x.ThisConv with ILThisConvention.Static -> true | _ -> false
+
+ static member Instance = ILCallingConvStatics.Instance
+ static member Static = ILCallingConvStatics.Static
+
+/// Static storage to amortize the allocation of ILCallingConv.Instance and ILCallingConv.Static
+and ILCallingConvStatics() =
+ static let instanceCallConv = Callconv(ILThisConvention.Instance,ILArgConvention.Default)
+ static let staticCallConv = Callconv(ILThisConvention.Static,ILArgConvention.Default)
+ static member Instance = instanceCallConv
+ static member Static = staticCallConv
+
+type ILBoxity =
+ | AsObject
+ | AsValue
+
+
+// IL type references have a pre-computed hash code to enable quick lookup tables during binary generation.
+[]
+type ILTypeRef =
+ { trefScope: ILScopeRef;
+ trefEnclosing: string list;
+ trefName: string;
+ hashCode : int
+ mutable asBoxedType: ILType }
+
+ static member Create(scope,enclosing,name) =
+ let hashCode = hash scope * 17 ^^^ (hash enclosing * 101 <<< 1) ^^^ (hash name * 47 <<< 2)
+ { trefScope=scope;
+ trefEnclosing= enclosing;
+ trefName=name;
+ hashCode=hashCode;
+ asBoxedType = Unchecked.defaultof<_> }
+
+ member x.Scope = x.trefScope
+ member x.Enclosing = x.trefEnclosing
+ member x.Name = x.trefName
+ member x.ApproxId = x.hashCode
+
+ member x.AsBoxedType (tspec:ILTypeSpec) =
+ match tspec.tspecInst.Length with
+ | 0 ->
+ let v = x.asBoxedType
+ match box v with
+ | null ->
+ let r = ILType.Boxed tspec
+ x.asBoxedType <- r
+ r
+ | _ -> v
+ | _ -> ILType.Boxed tspec
+
+ override x.GetHashCode() = x.hashCode
+ override x.Equals(yobj) =
+ let y = (yobj :?> ILTypeRef)
+ (x.ApproxId = y.ApproxId) &&
+ (x.Scope = y.Scope) &&
+ (x.Name = y.Name) &&
+ (x.Enclosing = y.Enclosing)
+ interface System.IComparable with
+ override x.CompareTo(yobj) =
+ let y = (yobj :?> ILTypeRef)
+ let c = compare x.ApproxId y.ApproxId
+ if c <> 0 then c else
+ let c = compare x.Scope y.Scope
+ if c <> 0 then c else
+ let c = compare x.Name y.Name
+ if c <> 0 then c else
+ compare x.Enclosing y.Enclosing
+
+ member tref.FullName = String.concat "." (tref.Enclosing @ [tref.Name])
+
+ member tref.BasicQualifiedName =
+ String.concat "+" (tref.Enclosing @ [ tref.Name ])
+
+ member tref.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
+ let sco = tref.Scope.QualifiedNameWithNoShortMscorlib
+ if sco = "" then basic else String.concat ", " [basic;sco]
+
+ member tref.QualifiedNameWithNoShortMscorlib =
+ tref.AddQualifiedNameExtensionWithNoShortMscorlib(tref.BasicQualifiedName)
+
+ member tref.QualifiedName =
+ let basic = tref.BasicQualifiedName
+ let sco = tref.Scope.QualifiedName
+ if sco = "" then basic else String.concat ", " [basic;sco]
+
+
+ override x.ToString() = x.FullName
+
+
+and
+ []
+ ILTypeSpec =
+ { tspecTypeRef: ILTypeRef;
+ /// The type instantiation if the type is generic
+ tspecInst: ILGenericArgs }
+ member x.TypeRef=x.tspecTypeRef
+ member x.Scope=x.TypeRef.Scope
+ member x.Enclosing=x.TypeRef.Enclosing
+ member x.Name=x.TypeRef.Name
+ member x.GenericArgs=x.tspecInst
+ static member Create(tref,inst) = { tspecTypeRef =tref; tspecInst=inst }
+ override x.ToString() = x.TypeRef.ToString() + (if ILList.isEmpty x.GenericArgs then "" else "<...>")
+ member x.BasicQualifiedName =
+ let tc = x.TypeRef.BasicQualifiedName
+ if ILList.isEmpty x.GenericArgs then
+ tc
+ else
+ tc + "[" + String.concat "," (x.GenericArgs |> ILList.map (fun arg -> "[" + arg.QualifiedNameWithNoShortMscorlib + "]")) + "]"
+
+ member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
+ x.TypeRef.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+
+ member x.FullName=x.TypeRef.FullName
+
+and []
+ ILType =
+ | Void
+ | Array of ILArrayShape * ILType
+ | Value of ILTypeSpec
+ | Boxed of ILTypeSpec
+ | Ptr of ILType
+ | Byref of ILType
+ | FunctionPointer of ILCallingSignature
+ | TypeVar of uint16
+ | Modified of bool * ILTypeRef * ILType
+
+ member x.BasicQualifiedName =
+ match x with
+ | ILType.TypeVar n -> "!" + string n
+ | ILType.Modified(_,_ty1,ty2) -> ty2.BasicQualifiedName
+ | ILType.Array (ILArrayShape(s),ty) -> ty.BasicQualifiedName + "[" + System.String(',',s.Length-1) + "]"
+ | ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName
+ | ILType.Void -> "void"
+ | ILType.Ptr _ty -> failwith "unexpected pointer type"
+ | ILType.Byref _ty -> failwith "unexpected byref type"
+ | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
+
+ member x.AddQualifiedNameExtensionWithNoShortMscorlib(basic) =
+ match x with
+ | ILType.TypeVar _n -> basic
+ | ILType.Modified(_,_ty1,ty2) -> ty2.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+ | ILType.Array (ILArrayShape(_s),ty) -> ty.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+ | ILType.Value tr | ILType.Boxed tr -> tr.AddQualifiedNameExtensionWithNoShortMscorlib(basic)
+ | ILType.Void -> failwith "void"
+ | ILType.Ptr _ty -> failwith "unexpected pointer type"
+ | ILType.Byref _ty -> failwith "unexpected byref type"
+ | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
+
+ member x.QualifiedNameWithNoShortMscorlib =
+ x.AddQualifiedNameExtensionWithNoShortMscorlib(x.BasicQualifiedName)
+
+and
+ []
+ IlxExtensionType =
+ | Ext_typ of obj
+ member x.Value = (let (Ext_typ(v)) = x in v)
+ override x.Equals(yobj) = match yobj with :? IlxExtensionType as y -> Unchecked.equals x.Value y.Value | _ -> false
+ interface System.IComparable with
+ override x.CompareTo(yobj) = match yobj with :? IlxExtensionType as y -> Unchecked.compare x.Value y.Value | _ -> invalidOp "bad comparison"
+
+and []
+ ILCallingSignature =
+ { CallingConv: ILCallingConv;
+ ArgTypes: ILTypes;
+ ReturnType: ILType }
+
+and ILGenericArgs = ILList
+and ILTypes = ILList
+
+
+let emptyILTypes = (ILList.empty : ILTypes)
+let emptyILGenericArgs = (ILList.empty: ILGenericArgs)
+
+let mkILTypes xs = (match xs with [] -> emptyILTypes | _ -> ILList.ofList xs)
+let mkILGenericArgs xs = (match xs with [] -> emptyILGenericArgs | _ -> ILList.ofList xs)
+
+let mkILCallSigRaw (cc,args,ret) = { ArgTypes=args; CallingConv=cc; ReturnType=ret}
+let mkILCallSig (cc,args,ret) = mkILCallSigRaw(cc, mkILTypes args, ret)
+let mkILBoxedType (tspec:ILTypeSpec) = tspec.TypeRef.AsBoxedType tspec
+
+type ILMethodRef =
+ { mrefParent: ILTypeRef;
+ mrefCallconv: ILCallingConv;
+ mrefGenericArity: int;
+ mrefName: string;
+ mrefArgs: ILTypes;
+ mrefReturn: ILType }
+ member x.EnclosingTypeRef = x.mrefParent
+ member x.CallingConv = x.mrefCallconv
+ member x.Name = x.mrefName
+ member x.GenericArity = x.mrefGenericArity
+ member x.ArgCount = x.mrefArgs.Length
+ member x.ArgTypes = x.mrefArgs
+ member x.ReturnType = x.mrefReturn
+
+ member x.CallingSignature = mkILCallSigRaw (x.CallingConv,x.ArgTypes,x.ReturnType)
+ static member Create(a,b,c,d,e,f) =
+ { mrefParent= a;mrefCallconv=b;mrefName=c;mrefGenericArity=d; mrefArgs=e;mrefReturn=f }
+ override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name + "(...)"
+
+
+[]
+type ILFieldRef =
+ { EnclosingTypeRef: ILTypeRef;
+ Name: string;
+ Type: ILType }
+ override x.ToString() = x.EnclosingTypeRef.ToString() + "::" + x.Name
+
+[]
+type ILMethodSpec =
+ { mspecMethodRef: ILMethodRef;
+ mspecEnclosingType: ILType;
+ mspecMethodInst: ILGenericArgs; }
+ static member Create(a,b,c) = { mspecEnclosingType=a; mspecMethodRef =b; mspecMethodInst=c }
+ member x.MethodRef = x.mspecMethodRef
+ member x.EnclosingType=x.mspecEnclosingType
+ member x.GenericArgs=x.mspecMethodInst
+ member x.Name=x.MethodRef.Name
+ member x.CallingConv=x.MethodRef.CallingConv
+ member x.GenericArity = x.MethodRef.GenericArity
+ member x.FormalArgTypes = x.MethodRef.ArgTypes
+ member x.FormalReturnType = x.MethodRef.ReturnType
+ override x.ToString() = x.MethodRef.ToString() + "(...)"
+
+
+type ILFieldSpec =
+ { FieldRef: ILFieldRef;
+ EnclosingType: ILType }
+ member x.FormalType = x.FieldRef.Type
+ member x.Name = x.FieldRef.Name
+ member x.EnclosingTypeRef = x.FieldRef.EnclosingTypeRef
+ override x.ToString() = x.FieldRef.ToString()
+
+
+// --------------------------------------------------------------------
+// Debug info.
+// --------------------------------------------------------------------
+
+type Guid = byte[]
+
+type ILPlatform =
+ | X86
+ | AMD64
+ | IA64
+
+type ILSourceDocument =
+ { sourceLanguage: Guid option;
+ sourceVendor: Guid option;
+ sourceDocType: Guid option;
+ sourceFile: string; }
+ static member Create(language,vendor,docType,file) =
+ { sourceLanguage=language;
+ sourceVendor=vendor;
+ sourceDocType=docType;
+ sourceFile=file; }
+ member x.Language=x.sourceLanguage
+ member x.Vendor=x.sourceVendor
+ member x.DocumentType=x.sourceDocType
+ member x.File=x.sourceFile
+
+type ILSourceMarker =
+ { sourceDocument: ILSourceDocument;
+ sourceLine: int;
+ sourceColumn: int;
+ sourceEndLine: int;
+ sourceEndColumn: int }
+ static member Create(document, line, column, endLine, endColumn) =
+ { sourceDocument=document;
+ sourceLine=line;
+ sourceColumn=column;
+ sourceEndLine=endLine;
+ sourceEndColumn=endColumn }
+ member x.Document=x.sourceDocument
+ member x.Line=x.sourceLine
+ member x.Column=x.sourceColumn
+ member x.EndLine=x.sourceEndLine
+ member x.EndColumn=x.sourceEndColumn
+ override x.ToString() = sprintf "(%d,%d)-(%d,%d)" x.Line x.Column x.EndLine x.EndColumn
+
+// --------------------------------------------------------------------
+// Custom attributes
+// --------------------------------------------------------------------
+
+type ILAttribElem =
+ | String of string option
+ | Bool of bool
+ | Char of char
+ | SByte of int8
+ | Int16 of int16
+ | Int32 of int32
+ | Int64 of int64
+ | Byte of uint8
+ | UInt16 of uint16
+ | UInt32 of uint32
+ | UInt64 of uint64
+ | Single of single
+ | Double of double
+ | Null
+ | Type of ILType option
+ | TypeRef of ILTypeRef option
+ | Array of ILType * ILAttribElem list
+
+type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem)
+type ILAttribute =
+ { Method: ILMethodSpec;
+#if SILVERLIGHT
+ Arguments: ILAttribElem list * ILAttributeNamedArg list
+#endif
+ Data: byte[] }
+
+[]
+type ILAttributes =
+ | CustomAttrsLazy of Lazy
+ | CustomAttrs of ILAttribute list
+ member x.AsList = match x with | CustomAttrsLazy l -> l.Force() | CustomAttrs l -> l
+
+type ILCodeLabel = int
+
+// --------------------------------------------------------------------
+// Instruction set.
+// --------------------------------------------------------------------
+
+type ILBasicType =
+ | DT_R
+ | DT_I1
+ | DT_U1
+ | DT_I2
+ | DT_U2
+ | DT_I4
+ | DT_U4
+ | DT_I8
+ | DT_U8
+ | DT_R4
+ | DT_R8
+ | DT_I
+ | DT_U
+ | DT_REF
+
+[]
+type ILToken =
+ | ILType of ILType
+ | ILMethod of ILMethodSpec
+ | ILField of ILFieldSpec
+
+[]
+type ILConst =
+ | I4 of int32
+ | I8 of int64
+ | R4 of single
+ | R8 of double
+
+type ILTailcall =
+ | Tailcall
+ | Normalcall
+
+type ILAlignment =
+ | Aligned
+ | Unaligned1
+ | Unaligned2
+ | Unaligned4
+
+type ILVolatility =
+ | Volatile
+ | Nonvolatile
+
+type ILReadonly =
+ | ReadonlyAddress
+ | NormalAddress
+
+type ILVarArgs = ILTypes option
+
+[]
+type ILComparisonInstr =
+ | BI_beq
+ | BI_bge
+ | BI_bge_un
+ | BI_bgt
+ | BI_bgt_un
+ | BI_ble
+ | BI_ble_un
+ | BI_blt
+ | BI_blt_un
+ | BI_bne_un
+ | BI_brfalse
+ | BI_brtrue
+
+
+[]
+type ILInstr =
+ | AI_add
+ | AI_add_ovf
+ | AI_add_ovf_un
+ | AI_and
+ | AI_div
+ | AI_div_un
+ | AI_ceq
+ | AI_cgt
+ | AI_cgt_un
+ | AI_clt
+ | AI_clt_un
+ | AI_conv of ILBasicType
+ | AI_conv_ovf of ILBasicType
+ | AI_conv_ovf_un of ILBasicType
+ | AI_mul
+ | AI_mul_ovf
+ | AI_mul_ovf_un
+ | AI_rem
+ | AI_rem_un
+ | AI_shl
+ | AI_shr
+ | AI_shr_un
+ | AI_sub
+ | AI_sub_ovf
+ | AI_sub_ovf_un
+ | AI_xor
+ | AI_or
+ | AI_neg
+ | AI_not
+ | AI_ldnull
+ | AI_dup
+ | AI_pop
+ | AI_ckfinite
+ | AI_nop
+ | AI_ldc of ILBasicType * ILConst
+ | I_ldarg of uint16
+ | I_ldarga of uint16
+ | I_ldind of ILAlignment * ILVolatility * ILBasicType
+ | I_ldloc of uint16
+ | I_ldloca of uint16
+ | I_starg of uint16
+ | I_stind of ILAlignment * ILVolatility * ILBasicType
+ | I_stloc of uint16
+
+ | I_br of ILCodeLabel
+ | I_jmp of ILMethodSpec
+ | I_brcmp of ILComparisonInstr * ILCodeLabel * ILCodeLabel (* second label is fall-through *)
+ | I_switch of (ILCodeLabel list * ILCodeLabel) (* last label is fallthrough *)
+ | I_ret
+
+ | I_call of ILTailcall * ILMethodSpec * ILVarArgs
+ | I_callvirt of ILTailcall * ILMethodSpec * ILVarArgs
+ | I_callconstraint of ILTailcall * ILType * ILMethodSpec * ILVarArgs
+ | I_calli of ILTailcall * ILCallingSignature * ILVarArgs
+ | I_ldftn of ILMethodSpec
+ | I_newobj of ILMethodSpec * ILVarArgs
+
+ | I_throw
+ | I_endfinally
+ | I_endfilter
+ | I_leave of ILCodeLabel
+ | I_rethrow
+
+ | I_ldsfld of ILVolatility * ILFieldSpec
+ | I_ldfld of ILAlignment * ILVolatility * ILFieldSpec
+ | I_ldsflda of ILFieldSpec
+ | I_ldflda of ILFieldSpec
+ | I_stsfld of ILVolatility * ILFieldSpec
+ | I_stfld of ILAlignment * ILVolatility * ILFieldSpec
+ | I_ldstr of string
+ | I_isinst of ILType
+ | I_castclass of ILType
+ | I_ldtoken of ILToken
+ | I_ldvirtftn of ILMethodSpec
+
+ | I_cpobj of ILType
+ | I_initobj of ILType
+ | I_ldobj of ILAlignment * ILVolatility * ILType
+ | I_stobj of ILAlignment * ILVolatility * ILType
+ | I_box of ILType
+ | I_unbox of ILType
+ | I_unbox_any of ILType
+ | I_sizeof of ILType
+
+ | I_ldelem of ILBasicType
+ | I_stelem of ILBasicType
+ | I_ldelema of ILReadonly * bool * ILArrayShape * ILType
+ | I_ldelem_any of ILArrayShape * ILType
+ | I_stelem_any of ILArrayShape * ILType
+ | I_newarr of ILArrayShape * ILType
+ | I_ldlen
+
+ | I_mkrefany of ILType
+ | I_refanytype
+ | I_refanyval of ILType
+
+ | I_break
+ | I_seqpoint of ILSourceMarker
+
+ | I_arglist
+
+ | I_localloc
+ | I_cpblk of ILAlignment * ILVolatility
+ | I_initblk of ILAlignment * ILVolatility
+
+ (* FOR EXTENSIONS, e.g. MS-ILX *)
+ | EI_ilzero of ILType
+ | EI_ldlen_multi of int32 * int32
+ | I_other of IlxExtensionInstr
+
+and IlxExtensionInstr = Ext_instr of obj
+
+
+// --------------------------------------------------------------------
+// Helpers for the ILX extensions
+// --------------------------------------------------------------------
+
+type internal_instr_extension =
+ { internalInstrExtIs: IlxExtensionInstr -> bool;
+ internalInstrExtDests: IlxExtensionInstr -> ILCodeLabel list;
+ internalInstrExtFallthrough: IlxExtensionInstr -> ILCodeLabel option;
+ internalInstrExtIsTailcall: IlxExtensionInstr -> bool;
+ internalInstrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> IlxExtensionInstr -> IlxExtensionInstr; }
+
+type ILInstrSetExtension<'T> =
+ { instrExtDests: 'T -> ILCodeLabel list;
+ instrExtFallthrough: 'T -> ILCodeLabel option;
+ instrExtIsTailcall: 'T -> bool;
+ instrExtRelabel: (ILCodeLabel -> ILCodeLabel) -> 'T -> 'T; }
+
+let instrExtensions = ref []
+
+let RegisterInstructionSetExtension (ext: ILInstrSetExtension<'T>) =
+ if nonNil !instrExtensions then failwith "RegisterInstructionSetExtension: only one extension currently allowed";
+ let mk (x: 'T) = Ext_instr (box x)
+ let test (Ext_instr _x) = true
+ let dest (Ext_instr x) = (unbox x : 'T)
+ instrExtensions :=
+ { internalInstrExtIs=test;
+ internalInstrExtDests=(fun x -> ext.instrExtDests (dest x));
+ internalInstrExtFallthrough=(fun x -> ext.instrExtFallthrough (dest x));
+ internalInstrExtIsTailcall=(fun x -> ext.instrExtIsTailcall (dest x));
+ internalInstrExtRelabel=(fun f x -> mk (ext.instrExtRelabel f (dest x))); }
+ :: !instrExtensions;
+ mk,test,dest
+
+let rec find_extension s f l =
+ let rec look l1 =
+ match l1 with
+ | [] -> failwith ("extension for "+s+" not found")
+ | (h::t) -> match f h with None -> look t | Some res -> res
+ look l
+
+
+type ILDebugMapping =
+ { LocalIndex: int;
+ LocalName: string; }
+
+type ILBasicBlock =
+ { Label: ILCodeLabel;
+ Instructions: ILInstr[] }
+ member bb.LastInstruction =
+ let n = bb.Instructions.Length
+ if n = 0 then failwith "last_of_bblock: empty bblock";
+ bb.Instructions.[n - 1]
+
+ member x.Fallthrough =
+ match x.LastInstruction with
+ | I_br l | I_brcmp (_,_,l) | I_switch (_,l) -> Some l
+ | I_other e -> find_extension "instr" (fun ext -> if ext.internalInstrExtIs e then Some (ext.internalInstrExtFallthrough e) else None) !instrExtensions
+ | _ -> None
+
+
+type ILCode =
+ | ILBasicBlock of ILBasicBlock
+ | GroupBlock of ILDebugMapping list * ILCode list
+ | RestrictBlock of ILCodeLabel list * ILCode
+ | TryBlock of ILCode * ILExceptionBlock
+
+and ILExceptionBlock =
+ | FaultBlock of ILCode
+ | FinallyBlock of ILCode
+ | FilterCatchBlock of (ILFilterBlock * ILCode) list
+
+and ILFilterBlock =
+ | TypeFilter of ILType
+ | CodeFilter of ILCode
+
+[]
+type ILLocal =
+ { Type: ILType;
+ IsPinned: bool }
+
+type ILLocals = ILList
+let emptyILLocals = (ILList.empty : ILLocals)
+let mkILLocals xs = (match xs with [] -> emptyILLocals | _ -> ILList.ofList xs)
+
+[]
+type ILMethodBody =
+ { IsZeroInit: bool;
+ MaxStack: int32;
+ NoInlining: bool;
+ Locals: ILLocals;
+ Code: ILCode;
+ SourceMarker: ILSourceMarker option }
+
+[]
+type ILMemberAccess =
+ | Assembly
+ | CompilerControlled
+ | FamilyAndAssembly
+ | FamilyOrAssembly
+ | Family
+ | Private
+ | Public
+
+[]
+[]
+type ILFieldInit =
+ | String of string
+ | Bool of bool
+ | Char of uint16
+ | Int8 of int8
+ | Int16 of int16
+ | Int32 of int32
+ | Int64 of int64
+ | UInt8 of uint8
+ | UInt16 of uint16
+ | UInt32 of uint32
+ | UInt64 of uint64
+ | Single of single
+ | Double of double
+ | Null
+
+// --------------------------------------------------------------------
+// Native Types, for marshalling to the native C interface.
+// These are taken directly from the ILASM syntax, and don't really
+// correspond yet to the ECMA Spec (Partition II, 7.4).
+// --------------------------------------------------------------------
+
+[]
+[]
+type ILNativeType =
+ | Empty
+ | Custom of Guid * string * string * byte[] (* guid,nativeTypeName,custMarshallerName,cookieString *)
+ | FixedSysString of int32
+ | FixedArray of int32
+ | Currency
+ | LPSTR
+ | LPWSTR
+ | LPTSTR
+ | ByValStr
+ | TBSTR
+ | LPSTRUCT
+ | Struct
+ | Void
+ | Bool
+ | Int8
+ | Int16
+ | Int32
+ | Int64
+ | Single
+ | Double
+ | Byte
+ | UInt16
+ | UInt32
+ | UInt64
+ | Array of ILNativeType option * (int32 * int32 option) option (* optional idx of parameter giving size plus optional additive i.e. num elems *)
+ | Int
+ | UInt
+ | Method
+ | AsAny
+ | BSTR
+ | IUnknown
+ | IDispatch
+ | Interface
+ | Error
+ | SafeArray of ILNativeVariant * string option
+ | ANSIBSTR
+ | VariantBool
+
+
+and ILNativeVariant =
+ | Empty
+ | Null
+ | Variant
+ | Currency
+ | Decimal
+ | Date
+ | BSTR
+ | LPSTR
+ | LPWSTR
+ | IUnknown
+ | IDispatch
+ | SafeArray
+ | Error
+ | HRESULT
+ | CArray
+ | UserDefined
+ | Record
+ | FileTime
+ | Blob
+ | Stream
+ | Storage
+ | StreamedObject
+ | StoredObject
+ | BlobObject
+ | CF
+ | CLSID
+ | Void
+ | Bool
+ | Int8
+ | Int16
+ | Int32
+ | Int64
+ | Single
+ | Double
+ | UInt8
+ | UInt16
+ | UInt32
+ | UInt64
+ | PTR
+ | Array of ILNativeVariant
+ | Vector of ILNativeVariant
+ | Byref of ILNativeVariant
+ | Int
+ | UInt
+
+type ILSecurityAction =
+ | Request
+ | Demand
+ | Assert
+ | Deny
+ | PermitOnly
+ | LinkCheck
+ | InheritCheck
+ | ReqMin
+ | ReqOpt
+ | ReqRefuse
+ | PreJitGrant
+ | PreJitDeny
+ | NonCasDemand
+ | NonCasLinkDemand
+ | NonCasInheritance
+ | LinkDemandChoice
+ | InheritanceDemandChoice
+ | DemandChoice
+
+type ILPermission =
+ | PermissionSet of ILSecurityAction * byte[]
+
+type ILPermissions =
+ | SecurityDecls of ILPermission list
+ | SecurityDeclsLazy of Lazy
+ member x.AsList = match x with SecurityDecls m -> m | SecurityDeclsLazy m -> m.Force()
+
+[]
+type PInvokeCharBestFit =
+ | UseAssembly
+ | Enabled
+ | Disabled
+
+[]
+type PInvokeThrowOnUnmappableChar =
+ | UseAssembly
+ | Enabled
+ | Disabled
+
+[]
+type PInvokeCallingConvention =
+ | None
+ | Cdecl
+ | Stdcall
+ | Thiscall
+ | Fastcall
+ | WinApi
+
+[]
+type PInvokeCharEncoding =
+ | None
+ | Ansi
+ | Unicode
+ | Auto
+
+[]
+type PInvokeMethod =
+ { Where: ILModuleRef;
+ Name: string;
+ CallingConv: PInvokeCallingConvention;
+ CharEncoding: PInvokeCharEncoding;
+ NoMangle: bool;
+ LastError: bool;
+ ThrowOnUnmappableChar: PInvokeThrowOnUnmappableChar;
+ CharBestFit: PInvokeCharBestFit }
+
+type ILParameter =
+ { Name: string option;
+ Type: ILType;
+ Default: ILFieldInit option;
+ Marshal: ILNativeType option;
+ IsIn: bool;
+ IsOut: bool;
+ IsOptional: bool;
+ CustomAttrs: ILAttributes }
+
+type ILParameters = ILList
+let emptyILParameters = (ILList.empty : ILParameters)
+
+let mkILParametersRaw x = (match x with [] -> emptyILParameters | _ -> ILList.ofList x)
+
+type ILReturn =
+ { Marshal: ILNativeType option;
+ Type: ILType;
+ CustomAttrs: ILAttributes }
+
+type ILOverridesSpec =
+ | OverridesSpec of ILMethodRef * ILType
+ member x.MethodRef = let (OverridesSpec(mr,_ty)) = x in mr
+ member x.EnclosingType = let (OverridesSpec(_mr,ty)) = x in ty
+
+type ILMethodVirtualInfo =
+ { IsFinal: bool
+ IsNewSlot: bool
+ IsCheckAccessOnOverride: bool
+ IsAbstract: bool }
+
+type MethodKind =
+ | Static
+ | Cctor
+ | Ctor
+ | NonVirtual
+ | Virtual of ILMethodVirtualInfo
+
+[]
+type MethodBody =
+ | IL of ILMethodBody
+ | PInvoke of PInvokeMethod (* platform invoke to native *)
+ | Abstract
+ | Native
+
+type ILLazyMethodBody =
+ | ILLazyMethodBody of Lazy
+ member x.Contents = let (ILLazyMethodBody mb) = x in mb.Force()
+
+[]
+type MethodCodeKind =
+ | IL
+ | Native
+ | Runtime
+
+let mkMethBodyAux mb = ILLazyMethodBody (Lazy.CreateFromValue mb)
+let mkMethBodyLazyAux mb = ILLazyMethodBody mb
+
+let typesOfILParamsRaw (ps:ILParameters) : ILTypes = ps |> ILList.map (fun p -> p.Type)
+let typesOfILParamsList (ps:ILParameter list) = ps |> List.map (fun p -> p.Type)
+
+[]
+type ILGenericVariance =
+ | NonVariant
+ | CoVariant
+ | ContraVariant
+
+type ILGenericParameterDef =
+ { Name: string;
+ Constraints: ILTypes;
+ Variance: ILGenericVariance;
+ HasReferenceTypeConstraint: bool;
+ CustomAttrs : ILAttributes;
+ HasNotNullableValueTypeConstraint: bool;
+ HasDefaultConstructorConstraint: bool; }
+
+ override x.ToString() = x.Name
+
+type ILGenericParameterDefs = ILGenericParameterDef list
+
+[]
+type ILMethodDef =
+ { Name: string;
+ mdKind: MethodKind;
+ CallingConv: ILCallingConv;
+ Parameters: ILParameters;
+ Return: ILReturn;
+ Access: ILMemberAccess;
+ mdBody: ILLazyMethodBody;
+ mdCodeKind: MethodCodeKind;
+ IsInternalCall: bool;
+ IsManaged: bool;
+ IsForwardRef: bool;
+ SecurityDecls: ILPermissions;
+ HasSecurity: bool;
+ IsEntryPoint:bool;
+ IsReqSecObj: bool;
+ IsHideBySig: bool;
+ IsSpecialName: bool;
+ IsUnmanagedExport: bool;
+ IsSynchronized: bool;
+ IsPreserveSig: bool;
+ IsMustRun: bool;
+ IsNoInline: bool;
+ GenericParams: ILGenericParameterDefs;
+ CustomAttrs: ILAttributes; }
+ member x.ParameterTypes = typesOfILParamsRaw x.Parameters
+ // Whidbey feature: SafeHandle finalizer must be run
+ member md.Code =
+ match md.mdBody.Contents with
+ | MethodBody.IL il-> Some il.Code
+ | _ -> None
+ member x.IsIL = match x.mdBody.Contents with | MethodBody.IL _ -> true | _ -> false
+ member x.Locals = match x.mdBody.Contents with | MethodBody.IL il -> il.Locals | _ -> emptyILLocals
+
+ member x.MethodBody = match x.mdBody.Contents with MethodBody.IL il -> il | _ -> failwith "not IL"
+
+ member x.SourceMarker = x.MethodBody.SourceMarker
+ member x.MaxStack = x.MethodBody.MaxStack
+ member x.IsZeroInit = x.MethodBody.IsZeroInit
+
+ member x.IsClassInitializer = match x.mdKind with | MethodKind.Cctor -> true | _ -> false
+ member x.IsConstructor = match x.mdKind with | MethodKind.Ctor -> true | _ -> false
+ member x.IsStatic = match x.mdKind with | MethodKind.Static -> true | _ -> false
+ member x.IsNonVirtualInstance = match x.mdKind with | MethodKind.NonVirtual -> true | _ -> false
+ member x.IsVirtual = match x.mdKind with | MethodKind.Virtual _ -> true | _ -> false
+
+ member x.IsFinal = match x.mdKind with | MethodKind.Virtual v -> v.IsFinal | _ -> invalidOp "not virtual"
+ member x.IsNewSlot = match x.mdKind with | MethodKind.Virtual v -> v.IsNewSlot | _ -> invalidOp "not virtual"
+ member x.IsCheckAccessOnOverride= match x.mdKind with | MethodKind.Virtual v -> v.IsCheckAccessOnOverride | _ -> invalidOp "not virtual"
+ member x.IsAbstract = match x.mdKind with | MethodKind.Virtual v -> v.IsAbstract | _ -> invalidOp "not virtual"
+
+ member md.CallingSignature = mkILCallSigRaw (md.CallingConv,md.ParameterTypes,md.Return.Type)
+
+
+/// Index table by name and arity.
+type MethodDefMap = Map
+
+[]
+type ILMethodDefs =
+ | Methods of Lazy
+ interface IEnumerable with
+ member x.GetEnumerator() = ((x :> IEnumerable).GetEnumerator() :> IEnumerator)
+ interface IEnumerable with
+ member x.GetEnumerator() =
+ let (Methods(lms)) = x
+ let ms,_ = lms.Force()
+ (ms :> IEnumerable).GetEnumerator()
+ member x.AsList = Seq.toList x
+
+ member x.FindByName nm =
+ let (Methods lpmap) = x
+ let t = snd (Lazy.force lpmap)
+ Map.tryFindMulti nm t
+
+ member x.FindByNameAndArity (nm,arity) =
+ x.FindByName nm |> List.filter (fun x -> x.Parameters.Length = arity)
+
+
+[]
+type ILEventDef =
+ { Type: ILType option;
+ Name: string;
+ IsRTSpecialName: bool;
+ IsSpecialName: bool;
+ AddMethod: ILMethodRef;
+ RemoveMethod: ILMethodRef;
+ FireMethod: ILMethodRef option;
+ OtherMethods: ILMethodRef list;
+ CustomAttrs: ILAttributes; }
+
+(* Index table by name. *)
+[]
+type ILEventDefs =
+ | Events of LazyOrderedMultiMap
+ member x.AsList = let (Events t) = x in t.Entries()
+ member x.LookupByName s = let (Events t) = x in t.[s]
+
+[]
+type ILPropertyDef =
+ { Name: string;
+ IsRTSpecialName: bool;
+ IsSpecialName: bool;
+ SetMethod: ILMethodRef option;
+ GetMethod: ILMethodRef option;
+ CallingConv: ILThisConvention;
+ Type: ILType;
+ Init: ILFieldInit option;
+ Args: ILTypes;
+ CustomAttrs: ILAttributes; }
+
+// Index table by name.
+[]
+type ILPropertyDefs =
+ | Properties of LazyOrderedMultiMap
+ member x.AsList = let (Properties t) = x in t.Entries()
+ member x.LookupByName s = let (Properties t) = x in t.[s]
+
+[]
+type ILFieldDef =
+ { Name: string;
+ Type: ILType;
+ IsStatic: bool;
+ Access: ILMemberAccess;
+ Data: byte[] option;
+ LiteralValue: ILFieldInit option;
+ Offset: int32 option;
+ IsSpecialName: bool;
+ Marshal: ILNativeType option;
+ NotSerialized: bool;
+ IsLiteral: bool ;
+ IsInitOnly: bool;
+ CustomAttrs: ILAttributes; }
+
+
+// Index table by name. Keep a canonical list to make sure field order is not disturbed for binary manipulation.
+type ILFieldDefs =
+ | Fields of LazyOrderedMultiMap
+ member x.AsList = let (Fields t) = x in t.Entries()
+ member x.LookupByName s = let (Fields t) = x in t.[s]
+
+type ILMethodImplDef =
+ { Overrides: ILOverridesSpec;
+ OverrideBy: ILMethodSpec }
+
+// Index table by name and arity.
+type ILMethodImplDefs =
+ | MethodImpls of Lazy
+ member x.AsList = let (MethodImpls ltab) = x in Map.foldBack (fun _x y r -> y@r) (ltab.Force()) []
+
+and MethodImplsMap = Map
+
+[]
+type ILTypeDefLayout =
+ | Auto
+ | Sequential of ILTypeDefLayoutInfo
+ | Explicit of ILTypeDefLayoutInfo (* REVIEW: add field info here *)
+
+and ILTypeDefLayoutInfo =
+ { Size: int32 option;
+ Pack: uint16 option }
+
+[]
+type ILTypeInit =
+ | BeforeField
+ | OnAny
+
+[]
+type ILDefaultPInvokeEncoding =
+ | Ansi
+ | Auto
+ | Unicode
+
+type ILTypeDefAccess =
+ | Public
+ | Private
+ | Nested of ILMemberAccess
+
+[]
+type ILTypeDefKind =
+ | Class
+ | ValueType
+ | Interface
+ | Enum
+ | Delegate
+ | Other of IlxExtensionTypeKind
+
+and IlxExtensionTypeKind = Ext_type_def_kind of obj
+
+type internal_type_def_kind_extension =
+ { internalTypeDefKindExtIs: IlxExtensionTypeKind -> bool; }
+
+
+[]
+type ILTypeDef =
+ { tdKind: ILTypeDefKind;
+ Name: string;
+ GenericParams: ILGenericParameterDefs; (* class is generic *)
+ Access: ILTypeDefAccess;
+ IsAbstract: bool;
+ IsSealed: bool;
+ IsSerializable: bool;
+ IsComInterop: bool; (* Class or interface generated for COM interop *)
+ Layout: ILTypeDefLayout;
+ IsSpecialName: bool;
+ Encoding: ILDefaultPInvokeEncoding;
+ NestedTypes: ILTypeDefs;
+ Implements: ILTypes;
+ Extends: ILType option;
+ Methods: ILMethodDefs;
+ SecurityDecls: ILPermissions;
+ HasSecurity: bool;
+ Fields: ILFieldDefs;
+ MethodImpls: ILMethodImplDefs;
+ InitSemantics: ILTypeInit;
+ Events: ILEventDefs;
+ Properties: ILPropertyDefs;
+ CustomAttrs: ILAttributes; }
+ member x.IsClass = (match x.tdKind with ILTypeDefKind.Class -> true | _ -> false)
+ member x.IsInterface = (match x.tdKind with ILTypeDefKind.Interface -> true | _ -> false)
+ member x.IsEnum = (match x.tdKind with ILTypeDefKind.Enum -> true | _ -> false)
+ member x.IsDelegate = (match x.tdKind with ILTypeDefKind.Delegate -> true | _ -> false)
+
+ member tdef.IsStructOrEnum =
+ match tdef.tdKind with
+ | ILTypeDefKind.ValueType | ILTypeDefKind.Enum -> true
+ | _ -> false
+
+
+and ILTypeDefs =
+ | TypeDefTable of Lazy<(string list * string * ILAttributes * Lazy) array> * Lazy
+ interface IEnumerable with
+ member x.GetEnumerator() = ((x :> IEnumerable).GetEnumerator() :> IEnumerator)
+ interface IEnumerable with
+ member x.GetEnumerator() =
+ let (TypeDefTable (larr,_tab)) = x
+ let tds = seq { for (_,_,_,td) in larr.Force() -> td.Force() }
+ tds.GetEnumerator()
+ member x.AsList = Seq.toList x
+
+ member x.AsListOfLazyTypeDefs = let (TypeDefTable (larr,_tab)) = x in larr.Force() |> Array.toList
+
+ member x.FindByName nm =
+ let (TypeDefTable (_,m)) = x
+ let ns,n = splitILTypeName nm
+ m.Force().[ns].[n].Force()
+
+
+/// keyed first on namespace then on type name. The namespace is often a unique key for a given type map.
+and ILTypeDefsMap =
+ Map>>
+
+type ILNestedExportedType =
+ { Name: string;
+ Access: ILMemberAccess;
+ Nested: ILNestedExportedTypes;
+ CustomAttrs: ILAttributes }
+
+and ILNestedExportedTypes =
+ | ILNestedExportedTypes of Lazy