Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New DotWeb.Debugger works great, all tests are passing once again, pr…

…eparing to merge with mater soon
  • Loading branch information...
commit 25bf8d794157c76ccb25a6dff12afaa7ee7f0f86 1 parent fd6326c
@flaub authored
Showing with 84 additions and 2,557 deletions.
  1. +0 −1  src/DotWeb.Hosting.Bridge/DotWeb.Hosting.Bridge.csproj
  2. +0 −125 src/DotWeb.Hosting.Bridge/HostingServer.cs
  3. +12 −4 src/DotWeb.Hosting.Bridge/JsBridge.cs
  4. +0 −143 src/DotWeb.Hosting.Weaver/AssemblyProcessor.cs
  5. +0 −161 src/DotWeb.Hosting.Weaver/CustomAttributeProcessor.cs
  6. +0 −115 src/DotWeb.Hosting.Weaver/DotWebSystemAssembly.cs
  7. +0 −172 src/DotWeb.Hosting.Weaver/ExceptionProcessor.cs
  8. +0 −52 src/DotWeb.Hosting.Weaver/ExternalAssembly.cs
  9. +0 −159 src/DotWeb.Hosting.Weaver/ExternalType.cs
  10. +0 −111 src/DotWeb.Hosting.Weaver/GenericProcessor.cs
  11. +0 −260 src/DotWeb.Hosting.Weaver/HostingWeaver.cs
  12. +0 −45 src/DotWeb.Hosting.Weaver/IResolver.cs
  13. +0 −68 src/DotWeb.Hosting.Weaver/IType.cs
  14. +0 −437 src/DotWeb.Hosting.Weaver/MethodProcessor.cs
  15. +0 −73 src/DotWeb.Hosting.Weaver/OpCodeConverter.cs
  16. +0 −68 src/DotWeb.Hosting.Weaver/ScopeProcessor.cs
  17. +68 −45 src/DotWeb.Hosting.Weaver/SimpleWeaver.cs
  18. +0 −378 src/DotWeb.Hosting.Weaver/TypeProcessor.cs
  19. +0 −1  test/DotWeb.Hosting.Test/DotWeb.Hosting.Test.csproj
  20. +4 −2 test/DotWeb.Hosting.Test/SessionHelper.cs
  21. +0 −137 test/DotWeb.Hosting.Test/Stash.cs
View
1  src/DotWeb.Hosting.Bridge/DotWeb.Hosting.Bridge.csproj
@@ -53,7 +53,6 @@
</Compile>
<Compile Include="CallContextStorage.cs" />
<Compile Include="DefaultFactory.cs" />
- <Compile Include="HostingServer.cs" />
<Compile Include="JsDynamicWrapper.cs" />
<Compile Include="IJsWrapper.cs" />
<Compile Include="IObjectFactory.cs" />
View
125 src/DotWeb.Hosting.Bridge/HostingServer.cs
@@ -1,125 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-
-using System.Net.Sockets;
-using System.Net;
-using System.IO;
-using DotWeb.Utility;
-using System;
-using System.Diagnostics;
-using DotWeb.Hosting.Weaver;
-using System.Threading;
-
-namespace DotWeb.Hosting.Bridge
-{
- public interface IHostingServer
- {
- string PrepareType(string binPath, AssemblyQualifiedTypeName aqtn);
-
- IPEndPoint EndPoint { get; }
-
- void Start();
- void Stop();
- }
-
- public static class HostingServerFactory
- {
- public static IHostingServer CreateHostingServer() {
- return new HostingServer();
- }
- }
-
- class HostingServer : IHostingServer
- {
- TcpListener listener;
-
- public HostingServer() {
- this.listener = new TcpListener(IPAddress.Loopback, 0);
- }
-
- public IPEndPoint EndPoint { get { return (IPEndPoint)this.listener.LocalEndpoint; } }
-
- public string PrepareType(string binPath, AssemblyQualifiedTypeName aqtn) {
- var weaver = new SimpleWeaver(binPath, binPath, new string[] { binPath }, false);
- string path = Path.Combine(binPath, aqtn.AssemblyName.Name);
- if (!path.EndsWith(".dll")) {
- path += ".dll";
- }
-
- var asm = weaver.ProcessAssembly(path);
- var asmName = asm.GetName();
- aqtn.AssemblyName.Name = asmName.Name;
- return aqtn.ToString();
- }
-
- public void Stop() {
- this.listener.Stop();
- }
-
- public void Start() {
- }
-
- private void OnAccept(IAsyncResult ar) {
- var listener = (TcpListener)ar.AsyncState;
- var client = listener.EndAcceptTcpClient(ar);
-
- RunInAppDomain(client);
- }
-
- private void RunInAppDomain(TcpClient client) {
- var curDomain = AppDomain.CurrentDomain;
- var setup = curDomain.SetupInformation;
-
- var appDomain = AppDomain.CreateDomain("DotWeb Hosting Environment", null, setup);
- var type = typeof(IsolatedContext);
- var context = (IsolatedContext)appDomain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
-
- try {
- context.Run(client.GetStream());
- }
- finally {
- client.Close();
- this.listener.Stop();
- AppDomain.Unload(appDomain);
- }
- }
-
- /// <summary>
- /// This allows static variables to be reset on each new request.
- /// It also serves as a good way to isolate each request from each other.
- /// </summary>
- class IsolatedContext : MarshalByRefObject
- {
- public void Run(NetworkStream stream) {
- HostedMode.Host = new CallContextStorage();
- try {
- var session = new RemoteSession(stream, stream);
- var factory = new DefaultFactory();
- var bridge = new JsBridge(session, factory);
- HostedMode.Host = bridge;
- bridge.DispatchForever();
- }
- catch (Exception ex) {
- Debug.WriteLine(ex);
- }
- finally {
- stream.Close();
- }
- }
- }
- }
-}
View
16 src/DotWeb.Hosting.Bridge/JsBridge.cs
@@ -20,7 +20,9 @@
using System.Linq;
using System.Reflection;
using System.Diagnostics;
+using System.IO;
using DotWeb.Utility;
+using DotWeb.Hosting.Weaver;
namespace DotWeb.Hosting.Bridge
{
@@ -31,8 +33,6 @@ namespace DotWeb.Hosting.Bridge
using ReferenceToObjectMap = Dictionary<int, object>;
using JsObjectToReferenceMap = Dictionary<object, int>;
- using System.IO;
- using DotWeb.Hosting.Weaver;
public class JsBridge : IDotWebHost
{
@@ -148,13 +148,21 @@ public class JsBridge : IDotWebHost
var typeName = parts[0].Trim();
var asmName = parts[1].Trim();
var binPath = parts[2].Trim();
- var weaver = new SimpleWeaver(binPath, binPath, new string[] { binPath }, false);
var asmPath = Path.Combine(binPath, asmName);
if (!asmPath.EndsWith(".dll")) {
asmPath += ".dll";
}
- var asm = weaver.ProcessAssembly(asmPath);
+
+ Assembly asm;
+ if (asmName.StartsWith("Hosted-")) {
+ // for testing
+ asm = Assembly.LoadFrom(asmPath);
+ }
+ else {
+ var weaver = new SimpleWeaver(binPath, binPath, new string[] { binPath }, false);
+ asm = weaver.ProcessAssembly(asmPath);
+ }
return asm.GetType(typeName);
}
View
143 src/DotWeb.Hosting.Weaver/AssemblyProcessor.cs
@@ -1,143 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Mono.Cecil;
-using System.Reflection;
-using System.Reflection.Emit;
-using Mono.Cecil.Cil;
-using System.IO;
-using DotWeb.Utility;
-using System.Diagnostics;
-using DotWeb.Hosting;
-
-namespace DotWeb.Hosting.Weaver
-{
- public class AssemblyProcessor : IAssembly
- {
- private IResolver resolver;
- private AssemblyDefinition asmDef;
- private ModuleDefinition moduleDef;
- private AssemblyBuilder asmBuilder;
- private ModuleBuilder moduleBuilder;
- private string fileName;
-
- private Dictionary<string, IType> typesByDef = new Dictionary<string, IType>();
-
- public const string HostedPrefix = "Hosted-";
-
- public Assembly Assembly { get { return this.asmBuilder; } }
-
- public AssemblyProcessor(IResolver resolver, AssemblyDefinition asmDef, string outputDir) {
- this.resolver = resolver;
- this.asmDef = asmDef;
- this.moduleDef = asmDef.MainModule;
- this.moduleDef.LoadSymbols();
-
- var name = asmDef.Name.Name;
- if (!name.StartsWith(HostedPrefix))
- name = HostedPrefix + name;
-
- this.fileName = name + ".dll";
- var asmName = new AssemblyName(name);
-
- this.asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave, outputDir);
- this.moduleBuilder = asmBuilder.DefineDynamicModule(name, this.fileName, true);
- }
-
- public Assembly ProcessModule() {
- foreach (TypeDefinition typeDef in this.moduleDef.Types) {
- if (typeDef.Name == Constants.ModuleType)
- continue;
-
- if (typeDef.Name.StartsWith("__StaticArrayInitTypeSize="))
- continue;
-
- IType item;
- if (!this.typesByDef.TryGetValue(typeDef.FullName, out item)) {
- item = ProcessType(typeDef);
- }
-
- item.Process();
- }
-
- foreach (var item in this.typesByDef.Values) {
- item.Close();
- }
-
- if (this.asmDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, this.asmDef, this.asmBuilder, null);
- }
-
- var type = typeof(AssemblyWeavedAttribute);
- var ctor = type.GetConstructor(Type.EmptyTypes);
- this.asmBuilder.SetCustomAttribute(new CustomAttributeBuilder(ctor, new object[0]));
-
- this.asmBuilder.Save(this.fileName);
-
- return this.asmBuilder;
- }
-
- private string GetTypeKey(TypeReference typeRef) {
- // TypeDefinition reports:
- // DotWeb.System.Collections.Generic.IEnumerable`1
- // TypeReference reports:
- // DotWeb.System.Collections.Generic.IEnumerable`1<T>
- // Proposal:
- // Resolve() all TypeReferences to TypeDefinitions to get a consistent key
-
- // NOTE: the above approach breaks resolution of array types (and GenericInstanceTypes)
- // because Resolve() removes the fact that the typeRef is an array.
- if (typeRef is TypeSpecification) {
- return typeRef.FullName;
- }
-
- return typeRef.Resolve().FullName;
- }
-
- public IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope) {
- IType type;
- string key = GetTypeKey(typeRef);
- if (!this.typesByDef.TryGetValue(key, out type)) {
- type = ProcessType(typeRef);
- }
-
- return type;
- }
-
- private IType ProcessType(TypeReference typeRef) {
- var typeDef = typeRef.Resolve();
- TypeBuilder outerBuilder = null;
- if (typeDef.IsNested) {
- var outerProc = this.resolver.ResolveTypeReference(typeDef.DeclaringType, null);
- outerBuilder = (TypeBuilder)outerProc.Type;
- }
-
- var typeProc = new TypeProcessor(this.resolver, this, typeDef, this.moduleBuilder, outerBuilder);
- RegisterType(typeRef, typeProc);
- return typeProc;
- }
-
- private void RegisterType(TypeReference typeRef, IType type) {
- string key = GetTypeKey(typeRef);
- this.typesByDef.Add(key, type);
- }
- }
-}
View
161 src/DotWeb.Hosting.Weaver/CustomAttributeProcessor.cs
@@ -1,161 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection.Emit;
-using Mono.Cecil;
-using System.Reflection;
-using System.Collections;
-
-namespace DotWeb.Hosting.Weaver
-{
- static class CustomAttributeProcessor
- {
- static CustomAttributeBuilder Process(IResolver resolver, CustomAttribute customAttribute, IGenericScope genericScope) {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(customAttribute.Constructor, genericScope);
- var type = ctor.DeclaringType;
-
- var ctorArgs = customAttribute.ConstructorParameters.Cast<object>().ToArray();
-
- var namedProperties = new PropertyInfo[customAttribute.Properties.Count];
- var propertyValues = new object[customAttribute.Properties.Count];
- var namedFields = new FieldInfo[customAttribute.Fields.Count];
- var fieldValues = new object[customAttribute.Fields.Count];
-
- int i = 0;
- foreach (DictionaryEntry entry in customAttribute.Properties) {
- string name = (string)entry.Key;
- var property = type.GetProperty(name);
- namedProperties[i] = property;
- propertyValues[i] = entry.Value;
- ++i;
- }
-
- i = 0;
- foreach (DictionaryEntry entry in customAttribute.Fields) {
- string name = (string)entry.Key;
- var field = type.GetField(name);
- namedFields[i] = field;
- fieldValues[i] = entry.Value;
- ++i;
- }
-
- var builder = new CustomAttributeBuilder(ctor, ctorArgs, namedProperties, propertyValues, namedFields, fieldValues);
- return builder;
- }
-
- public static void Process(IResolver resolver, PropertyDefinition def, PropertyBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, FieldDefinition def, FieldBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, MethodDefinition def, MethodBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, MethodDefinition def, ConstructorBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, TypeDefinition def, TypeBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, EventDefinition def, EventBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, AssemblyDefinition def, AssemblyBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
-
- public static void Process(IResolver resolver, TypeDefinition def, EnumBuilder builder, IGenericScope genericScope) {
- foreach (CustomAttribute item in def.CustomAttributes) {
- if (item.Blob == null) {
- builder.SetCustomAttribute(CustomAttributeProcessor.Process(resolver, item, genericScope));
- }
- else {
- var ctor = (ConstructorInfo)resolver.ResolveMethodReference(item.Constructor, genericScope);
- builder.SetCustomAttribute(ctor, item.Blob);
- }
- }
- }
- }
-}
View
115 src/DotWeb.Hosting.Weaver/DotWebSystemAssembly.cs
@@ -1,115 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Mono.Cecil;
-using System.Reflection;
-
-namespace DotWeb.Hosting.Weaver
-{
- class DotWebSystemAssembly : ITypeResolver
- {
- private IResolver resolver;
- private Assembly asm;
- private Type useSystemAttribute;
- private Dictionary<TypeReference, ExternalType> cache = new Dictionary<TypeReference, ExternalType>();
-
- public DotWebSystemAssembly(IResolver resolver) {
- this.resolver = resolver;
- this.asm = Assembly.Load("Hosted-DotWeb.System");
- this.useSystemAttribute = this.asm.GetType("DotWeb.System.DotWeb.UseSystemAttribute");
- }
-
- public IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope) {
- ExternalType ret;
- if (this.cache.TryGetValue(typeRef, out ret)) {
- return ret;
- }
-
- // need to deal with the following kinds references:
- // * Foo Simple
- // * Foo[] ArrayType of Simple
- // * List<Foo> GenericInstanceType of Simple
- // * List<Foo>[] ArrayType of GenericInstanceType of Simple
- // * List<Foo[]> GenericInstanceType of ArrayType of Simple
-
- if (typeRef is GenericInstanceType) {
- ret = ResolveGenericType(typeRef, (GenericInstanceType)typeRef);
- }
- else if (typeRef is ArrayType) {
- ret = ResolveArrayType(typeRef, (ArrayType)typeRef);
- }
- else {
- ret = ResolveSimpleType(typeRef);
- }
-
- this.cache.Add(typeRef, ret);
-
- return ret;
- }
-
- private string ConvertName(TypeReference typeRef) {
- return string.Format("DotWeb.{0}", typeRef.FullName.Replace("/", "+"));
- }
-
- private Type MakeArrayType(Type type, int rank) {
- if (rank == 1)
- return type.MakeArrayType();
- return type.MakeArrayType(rank);
- }
-
- private ExternalType ResolveArrayType(TypeReference typeRef, ArrayType arrayTypeSpec) {
- var elementType = this.resolver.ResolveTypeReference(arrayTypeSpec.ElementType, null);
- return new ExternalType(this.resolver, MakeArrayType(elementType.Type, arrayTypeSpec.Rank));
- }
-
- private ExternalType ResolveGenericType(TypeReference typeRef, GenericInstanceType genericTypeSpec) {
- var originalTypeRef = genericTypeSpec.GetOriginalType();
- var modifiedName = ConvertName(originalTypeRef);
- var genericType = this.asm.GetType(modifiedName);
-
- // The [UseSystem] attribute lives on the genericType, not the concreteType (which is generated)
- if (genericType.IsDefined(this.useSystemAttribute, false)) {
- string sysFullName = typeRef.FullName.Replace("/", "+");
- return new ExternalType(this.resolver, Type.GetType(sysFullName));
- }
- else {
- var genericArgumentRefs = genericTypeSpec.GenericArguments.Cast<TypeReference>();
- var typeArguments = genericArgumentRefs.Select(x => this.resolver.ResolveTypeReference(x, null).Type).ToArray();
- var concreteType = genericType.MakeGenericType(typeArguments);
-
- return new ExternalType(this.resolver, concreteType);
- }
- }
-
- private ExternalType ResolveSimpleType(TypeReference typeRef) {
- var modifiedName = ConvertName(typeRef);
- var type = this.asm.GetType(modifiedName);
-
- if (type.IsDefined(this.useSystemAttribute, false)) {
- string sysFullName = typeRef.FullName.Replace("/", "+");
- return new ExternalType(this.resolver, Type.GetType(sysFullName));
- }
- else {
- return new ExternalType(this.resolver, type);
- }
- }
- }
-}
View
172 src/DotWeb.Hosting.Weaver/ExceptionProcessor.cs
@@ -1,172 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Mono.Cecil.Cil;
-using System.Reflection.Emit;
-using System.Collections;
-
-namespace DotWeb.Hosting.Weaver
-{
- class ExceptionProcessor
- {
- enum ExceptionLabelType
- {
- Start,
- End,
- Catch,
- Finally
- }
-
- class InstructionRange
- {
- public int Start { get; set; }
- public int End { get; set; }
-
- public InstructionRange(int start, int end) {
- this.Start = start;
- this.End = end;
- }
-
- public override bool Equals(object obj) {
- var rhs = obj as InstructionRange;
- if (rhs == null) {
- return false;
- }
- return this.Start == rhs.Start && this.End == rhs.End;
- }
-
- public override int GetHashCode() {
- return Start ^ End;
- }
- }
-
- class ExceptionLabel
- {
- public ExceptionLabelType Type { get; set; }
- public Type CatchType { get; set; }
- }
-
- class LabelDictionary
- {
- private Dictionary<InstructionRange, ExceptionLabel> labels;
-
- public LabelDictionary() {
- this.labels = new Dictionary<InstructionRange, ExceptionLabel>();
- }
-
- public IEnumerable<ExceptionLabel> GetAllWithStart(int start) {
- var result = new List<ExceptionLabel>();
- foreach (var entry in this.labels) {
- if (entry.Key.Start == start) {
- result.Add(entry.Value);
- }
- }
- return result;
- }
-
- public bool TryGetValue(InstructionRange key, out ExceptionLabel value) {
- return this.labels.TryGetValue(key, out value);
- }
-
- public void Add(InstructionRange key, ExceptionLabel value) {
- this.labels.Add(key, value);
- }
- }
-
- private MethodProcessor parent;
- private ILGenerator generator;
- private LabelDictionary labels = new LabelDictionary();
-
- public ExceptionProcessor(MethodProcessor parent, ILGenerator generator) {
- this.parent = parent;
- this.generator = generator;
- }
-
- public void Start(ExceptionHandlerCollection handlers) {
- var ends = new Dictionary<InstructionRange, int>();
-
- foreach (ExceptionHandler handler in handlers) {
- var tryRange = new InstructionRange(handler.TryStart.Offset, handler.TryEnd.Offset);
- ExceptionLabel tryLabel;
- if (!this.labels.TryGetValue(tryRange, out tryLabel)) {
- tryLabel = new ExceptionLabel {
- Type = ExceptionLabelType.Start
- };
- this.labels.Add(tryRange, tryLabel);
- }
-
- var handlerRange = new InstructionRange(handler.HandlerStart.Offset, handler.HandlerEnd.Offset);
- ExceptionLabel handlerLabel;
- if (!this.labels.TryGetValue(handlerRange, out handlerLabel)) {
- handlerLabel = new ExceptionLabel();
- switch (handler.Type) {
- case ExceptionHandlerType.Catch:
- handlerLabel.Type = ExceptionLabelType.Catch;
- handlerLabel.CatchType = this.parent.ResolveTypeReference(handler.CatchType);
- break;
- case ExceptionHandlerType.Finally:
- handlerLabel.Type = ExceptionLabelType.Finally;
- break;
- default:
- throw new NotSupportedException();
- }
- this.labels.Add(handlerRange, handlerLabel);
- }
-
- int end = 0;
- ends.TryGetValue(tryRange, out end);
-
- end = Math.Max(end, handler.TryEnd.Offset);
- end = Math.Max(end, handler.HandlerEnd.Offset);
-
- ends[tryRange] = end;
- }
-
- foreach (var end in ends.Values) {
- var endLabel = new ExceptionLabel { Type = ExceptionLabelType.End };
- var endRange = new InstructionRange(end, end);
- this.labels.Add(endRange, endLabel);
- }
- }
-
- public void ProcessInstruction(Instruction cil) {
- var blocks = this.labels.GetAllWithStart(cil.Offset);
- foreach (var block in blocks) {
- switch (block.Type) {
- case ExceptionLabelType.Start:
- this.generator.BeginExceptionBlock();
- break;
- case ExceptionLabelType.End:
- this.generator.EndExceptionBlock();
- break;
- case ExceptionLabelType.Catch:
- this.generator.BeginCatchBlock(block.CatchType);
- break;
- case ExceptionLabelType.Finally:
- this.generator.BeginFinallyBlock();
- break;
- }
- }
- }
- }
-
-}
View
52 src/DotWeb.Hosting.Weaver/ExternalAssembly.cs
@@ -1,52 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using Mono.Cecil;
-
-namespace DotWeb.Hosting.Weaver
-{
- class ExternalAssembly : IAssembly
- {
- private IResolver resolver;
- private Assembly asm;
- private Dictionary<TypeReference, ExternalType> cache = new Dictionary<TypeReference, ExternalType>();
-
- public Assembly Assembly { get { return this.asm; } }
-
- public ExternalAssembly(IResolver resolver, Assembly asm) {
- this.resolver = resolver;
- this.asm = asm;
- }
-
- public IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope) {
- ExternalType ret;
- if (!this.cache.TryGetValue(typeRef, out ret)) {
- string fullName = typeRef.FullName.Replace("/", "+");
- var type = this.asm.GetType(fullName);
- ret = new ExternalType(this.resolver, type);
- if (ret == null)
- throw new NullReferenceException(string.Format("Could not find Type: {0}", typeRef.ToString()));
- this.cache.Add(typeRef, ret);
- }
- return ret;
- }
- }
-}
View
159 src/DotWeb.Hosting.Weaver/ExternalType.cs
@@ -1,159 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Mono.Cecil;
-using System.Reflection.Emit;
-using System.Diagnostics;
-
-namespace DotWeb.Hosting.Weaver
-{
- class ExternalType : IType
- {
- public static readonly IType Void = new ExternalType(null, typeof(void));
-
- private IResolver resolver;
-
- private const BindingFlags Flags =
- BindingFlags.DeclaredOnly |
- BindingFlags.Instance |
- BindingFlags.Static |
- BindingFlags.Public |
- BindingFlags.NonPublic;
-
- private const BindingFlags StaticFlags =
- BindingFlags.DeclaredOnly |
- BindingFlags.Static |
- BindingFlags.Public |
- BindingFlags.NonPublic;
-
- private const BindingFlags InstanceFlags =
- BindingFlags.DeclaredOnly |
- BindingFlags.Instance |
- BindingFlags.Public |
- BindingFlags.NonPublic;
-
- public Type Type { get; protected set; }
-
- public ExternalType(IResolver resolver, Type type) {
- if (type == null)
- throw new ArgumentNullException("type");
- this.resolver = resolver;
- this.Type = type;
- }
-
- public override string ToString() {
- return string.Format("ExternalType: {0}", this.Type.ToString());
- }
-
- public virtual MethodBase ResolveMethod(MethodReference methodRef) {
- var argDefs = methodRef.Parameters.Cast<ParameterDefinition>();
- var types = argDefs.Select(x => ResolveTypeReference(x)).ToArray();
- if (methodRef.Name == ConstructorInfo.ConstructorName) {
- var ret = this.Type.GetConstructor(InstanceFlags, null, types, null);
- if (ret == null)
- throw new NullReferenceException(string.Format("Could not find ctor: {0}", methodRef.ToString()));
- return ret;
- }
- else if (methodRef.Name == ConstructorInfo.TypeConstructorName) {
- var ret = this.Type.GetConstructor(StaticFlags, null, types, null);
- if (ret == null)
- throw new NullReferenceException(string.Format("Could not find ctor: {0}", methodRef.ToString()));
- return ret;
- }
- else {
- var ret = this.Type.GetMethod(methodRef.Name, Flags, Type.DefaultBinder, types, null);
- if (ret == null)
- throw new NullReferenceException(string.Format("Could not find method: {0}", methodRef.ToString()));
- return ret;
- }
- }
-
- public virtual FieldInfo ResolveField(FieldDefinition fieldDef) {
- var ret = this.Type.GetField(fieldDef.Name, Flags);
- if (ret == null)
- throw new NullReferenceException(string.Format("Could not find field: {0}", fieldDef.ToString()));
- return ret;
- }
-
- protected Type ResolveTypeReference(ParameterDefinition parameterDef) {
- if (parameterDef.ParameterType.Name.StartsWith("!")) {
- var genericArg = (GenericParameter)parameterDef.ParameterType;
- var args = this.Type.GetGenericArguments();
- return args[genericArg.Position];
- }
- return this.resolver.ResolveTypeReference(parameterDef.ParameterType, null).Type;
- }
-
- public virtual void Close() {
- }
-
- public virtual void Process() {
- }
- }
-
- class GenericType : IType
- {
- private IResolver resolver;
- private Type concreteType;
- private TypeProcessor genericTypeProc;
-
- public GenericType(IResolver resolver, TypeProcessor genericTypeProc, Type concreteType) {
- this.resolver = resolver;
- this.genericTypeProc = genericTypeProc;
- this.concreteType = concreteType;
- }
-
- public override string ToString() {
- return string.Format("GenericType: [{0}]", this.Type.ToString());
- }
-
- public Type Type {
- get { return this.concreteType; }
- }
-
- public TypeProcessor GenericTypeProc { get { return this.genericTypeProc; } }
-
- public void Close() {
- throw new NotImplementedException();
- }
-
- public void Process() {
- throw new NotImplementedException();
- }
-
- public MethodBase ResolveMethod(MethodReference methodRef) {
- var genericMethod = this.genericTypeProc.ResolveMethod(methodRef);
- if (methodRef.Name == ConstructorInfo.ConstructorName) {
- return TypeBuilder.GetConstructor(this.concreteType, (ConstructorInfo)genericMethod);
- }
- else {
- return TypeBuilder.GetMethod(this.concreteType, (MethodInfo)genericMethod);
- }
- }
-
- public FieldInfo ResolveField(FieldDefinition fieldDef) {
- var genericField = this.genericTypeProc.ResolveField(fieldDef);
- return TypeBuilder.GetField(this.concreteType, genericField);
- }
- }
-}
View
111 src/DotWeb.Hosting.Weaver/GenericProcessor.cs
@@ -1,111 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Mono.Cecil;
-using System.Reflection.Emit;
-using SR = System.Reflection;
-
-namespace DotWeb.Hosting.Weaver
-{
- class GenericProcessorBase : IGenericScope
- {
- private ITypeResolver resolver;
- private Dictionary<string, GenericTypeParameterBuilder> byName = new Dictionary<string, GenericTypeParameterBuilder>();
-
- protected GenericProcessorBase(ITypeResolver resolver) {
- this.resolver = resolver;
- }
-
- private GenericTypeParameterBuilder GetParameterByName(string name) {
- GenericTypeParameterBuilder ret = null;
- this.byName.TryGetValue(name, out ret);
- return ret;
- }
-
- public Type ResolveGenericParameter(TypeReference typeRef) {
- // need to deal with T[]
- if (typeRef is ArrayType) {
- var arrayType = (ArrayType)typeRef;
- var builder = GetParameterByName(arrayType.ElementType.Name);
- if (builder == null)
- return null;
- if (arrayType.Rank == 1)
- return builder.MakeArrayType();
- return builder.MakeArrayType(arrayType.Rank);
- }
- return GetParameterByName(typeRef.Name);
- }
-
- protected void ProcessParameter(GenericParameter genericParameter, GenericTypeParameterBuilder genericBuilder) {
- genericBuilder.SetGenericParameterAttributes((SR.GenericParameterAttributes)genericParameter.Attributes);
-
- if (genericParameter.HasConstraints) {
- var interfaces = new List<Type>();
-
- foreach (TypeReference item in genericParameter.Constraints) {
- var constraint = item.Resolve();
- var type = this.resolver.ResolveTypeReference(constraint, this).Type;
- if (constraint.IsInterface) {
- interfaces.Add(type);
- }
- else {
- genericBuilder.SetBaseTypeConstraint(type);
- }
- }
-
- if (interfaces.Any()) {
- genericBuilder.SetInterfaceConstraints(interfaces.ToArray());
- }
- }
- }
-
- protected void ProcessGenericParameters(GenericParameterCollection args, GenericTypeParameterBuilder[] builders) {
- foreach (var builder in builders) {
- byName.Add(builder.Name, builder);
- }
-
- foreach (GenericParameter arg in args) {
- var builder = byName[arg.Name];
- ProcessParameter(arg, builder);
- }
- }
- }
-
- class GenericProcessor : GenericProcessorBase
- {
- public GenericProcessor(ITypeResolver resolver)
- : base(resolver) {
- }
-
- public void ProcessType(TypeDefinition typeDef, TypeBuilder typeBuilder) {
- var names = typeDef.GenericParameters.Cast<GenericParameter>().Select(x => x.Name);
- var builders = typeBuilder.DefineGenericParameters(names.ToArray());
- ProcessGenericParameters(typeDef.GenericParameters, builders);
- }
-
- public void ProcessMethod(MethodDefinition methodDef, MethodBuilder methodBuilder) {
- var names = methodDef.GenericParameters.Cast<GenericParameter>().Select(x => x.Name);
- var builders = methodBuilder.DefineGenericParameters(names.ToArray());
- ProcessGenericParameters(methodDef.GenericParameters, builders);
- }
- }
-}
View
260 src/DotWeb.Hosting.Weaver/HostingWeaver.cs
@@ -1,260 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Mono.Cecil;
-using System.Reflection.Emit;
-using System.IO;
-using System.Diagnostics;
-using DotWeb.Hosting;
-using DotWeb.Utility.Cecil;
-
-namespace DotWeb.Hosting.Weaver
-{
- public class HostingWeaver : IResolver
- {
- class ConstantNames
- {
- public const string DotWebSystem = "DotWeb.System";
- public const string DotWebSystemDll = "DotWeb.System.dll";
- public const string Mscorlib = "mscorlib";
- public const string SystemCore = "System.Core";
- public const string SystemCoreDll = "System.Core.dll";
- public const string AssemblyWeavedAttribute = "AssemblyWeavedAttribute";
- public const string CommonLanguageRuntimeLibrary = "CommonLanguageRuntimeLibrary";
- }
-
- private bool forceBuild;
- private string inputDir;
- private string outputDir;
- private GlobalAssemblyResolver asmResolver = new GlobalAssemblyResolver();
- private Dictionary<string, ITypeResolver> modules = new Dictionary<string, ITypeResolver>();
-
- public HostingWeaver(string inputDir, string outputDir, string[] searchDirs, bool forceBuild) {
- this.inputDir = inputDir;
- this.outputDir = outputDir;
- this.forceBuild = forceBuild;
-
- this.asmResolver.AddSearchDirectory(this.inputDir);
- if (searchDirs != null) {
- foreach (var dir in searchDirs) {
- this.asmResolver.AddSearchDirectory(dir);
- }
- }
-
- PrepareMscorlib();
- PrepareSystemCore();
- }
-
- private ExternalAssembly LoadSystemAssembly(Type sysType) {
- var asm = sysType.Assembly;
- var asmName = AssemblyNameReference.Parse(asm.FullName);
- var asmDef = this.asmResolver.Resolve(asmName);
- return new ExternalAssembly(this, asm);
- }
-
- private void PrepareMscorlib() {
- var asm = LoadSystemAssembly(typeof(object));
- this.modules.Add(ConstantNames.Mscorlib, asm);
- this.modules.Add(ConstantNames.CommonLanguageRuntimeLibrary, asm);
- }
-
- private void PrepareSystemCore() {
- var asm = LoadSystemAssembly(typeof(Action));
- this.modules.Add(ConstantNames.SystemCore, asm);
- this.modules.Add(ConstantNames.SystemCoreDll, asm);
- }
-
- private void PrepareDotWebSystem() {
- var proc = new DotWebSystemAssembly(this);
- this.modules.Add(ConstantNames.DotWebSystem, proc);
- this.modules.Add(ConstantNames.DotWebSystemDll, proc);
- }
-
- /// <summary>
- /// This should ONLY be called for the top level assembly,
- /// otherwise we get different resolvers and therefore different
- /// assembly definitions for the same assembly
- /// </summary>
- /// <param name="asmPath"></param>
- /// <returns></returns>
- public Assembly ProcessAssembly(string asmPath) {
- var asmDef = AssemblyFactory.GetAssembly(asmPath);
- asmDef.Resolver = this.asmResolver;
-
- foreach (CustomAttribute item in asmDef.CustomAttributes) {
- if (item.Constructor.DeclaringType.Name == ConstantNames.AssemblyWeavedAttribute) {
- Console.WriteLine("This assembly has already been weaved and is ready for hosted mode");
- return Assembly.LoadFrom(asmPath);
- }
- }
-
- return ProcessAssembly(asmDef, new HashSet<string>()).Assembly;
- }
-
- // depth-first recursion so that we make sure to re-weave dependant assemblies when necessary
- private IAssembly ProcessAssembly(AssemblyDefinition asmDef, HashSet<string> visited) {
- var dependencyChanged = false;
- foreach (AssemblyNameReference asmRef in asmDef.MainModule.AssemblyReferences) {
- if (visited.Contains(asmRef.Name))
- continue;
-
- visited.Add(asmRef.Name);
-
- if (this.modules.ContainsKey(asmRef.Name))
- continue;
-
- if (asmRef.Name == ConstantNames.DotWebSystem) {
- PrepareDotWebSystem();
- continue;
- }
-
- var child = this.asmResolver.Resolve(asmRef);
- var childAsm = ProcessAssembly(child, visited);
- if (childAsm is AssemblyProcessor) {
- // otherwise it'd be an ExternalAssembly and thus didn't need processing
- dependencyChanged = true;
- }
- }
-
- string name = asmDef.MainModule.Name;
- string altName = Path.GetFileNameWithoutExtension(name);
-
- string hostedName = name;
- if (!hostedName.StartsWith(AssemblyProcessor.HostedPrefix))
- hostedName = AssemblyProcessor.HostedPrefix + hostedName;
-
- string path = Path.Combine(this.outputDir, MakeAssemblyNameIntoFilename(hostedName));
- string srcPath = Path.Combine(this.inputDir, MakeAssemblyNameIntoFilename(name));
-
- if (!this.forceBuild &&
- File.Exists(path) &&
- File.GetLastWriteTime(srcPath) < File.GetLastWriteTime(path) &&
- !dependencyChanged) {
- var asm = Assembly.LoadFrom(path);
- var proc = new ExternalAssembly(this, asm);
- this.AddModule(name, altName, proc);
- return proc;
- }
- else {
- var proc = new AssemblyProcessor(this, asmDef, this.outputDir);
- this.AddModule(name, altName, proc);
- proc.ProcessModule();
- return proc;
- }
- }
-
- private void AddModule(string name, string altName, ITypeResolver proc) {
- this.modules.Add(name, proc);
- if (name != altName)
- this.modules.Add(altName, proc);
- }
-
- private string MakeAssemblyNameIntoFilename(string name) {
- if (!name.EndsWith(".dll"))
- return name + ".dll";
- return name;
- }
-
- private IType ResolveTypeSpecification(TypeSpecification typeSpec, IGenericScope genericScope) {
- if (typeSpec is ArrayType) {
- var arrayType = (ArrayType)typeSpec;
- var elementProc = ResolveTypeReference(arrayType.ElementType, genericScope);
- Type realType;
- if (arrayType.Rank == 1)
- realType = elementProc.Type.MakeArrayType();
- else
- realType = elementProc.Type.MakeArrayType(arrayType.Rank);
- var externalWrapper = new ExternalType(this, realType);
- return externalWrapper;
- }
-
- if (typeSpec is GenericInstanceType) {
- var typeDef = typeSpec.Resolve();
- var genericTypeProc = ResolveTypeReference(typeDef, genericScope);
- var genericInstanceType = (GenericInstanceType)typeSpec;
- var genericArgumentRefs = genericInstanceType.GenericArguments.Cast<TypeReference>();
- var typeArguments = genericArgumentRefs.Select(x => ResolveTypeReference(x, genericScope).Type).ToArray();
- var concreteType = genericTypeProc.Type.MakeGenericType(typeArguments);
- if (genericTypeProc is ExternalType) {
- return new ExternalType(this, concreteType);
- }
- else {
- return new GenericType(this, (TypeProcessor)genericTypeProc, concreteType);
- }
- }
-
- if (typeSpec is ReferenceType) {
- var elementType = ResolveTypeReference(typeSpec.ElementType, genericScope);
- var refType = elementType.Type.MakeByRefType();
- return new SimpleType(refType);
- }
-
- throw new NotSupportedException();
- }
-
- #region IResolver Members
-
- public IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope) {
- if (typeRef.FullName == Constants.Void) {
- return ExternalType.Void;
- }
-
- if (typeRef is TypeSpecification) {
- return ResolveTypeSpecification((TypeSpecification)typeRef, genericScope);
- }
-
- if (typeRef is GenericParameter) {
- var type = genericScope.ResolveGenericParameter(typeRef);
- var simpleType = new SimpleType(type);
- return simpleType;
- }
-
- var scope = typeRef.Scope;
- string key;
- if (scope == null)
- key = ConstantNames.Mscorlib;
- else
- key = scope.Name;
- var moduleProc = this.modules[key];
- var typeProc = moduleProc.ResolveTypeReference(typeRef, genericScope);
- return typeProc;
- }
-
- public MethodBase ResolveMethodReference(MethodReference methodRef, IGenericScope genericScope) {
- var type = ResolveTypeReference(methodRef.DeclaringType, genericScope);
- if (type == null)
- throw new NullReferenceException(string.Format("Could not find DeclaringType for method: {0}", methodRef.ToString()));
- return type.ResolveMethod(methodRef);
- }
-
- public FieldInfo ResolveFieldReference(FieldReference fieldRef, IGenericScope genericScope) {
- var fieldDef = fieldRef.Resolve();
- var type = ResolveTypeReference(fieldDef.DeclaringType, genericScope);
- if (type == null)
- throw new NullReferenceException(string.Format("Could not find DeclaringType for field: {0}", fieldRef.ToString()));
- return type.ResolveField(fieldDef);
- }
-
- #endregion
- }
-}
View
45 src/DotWeb.Hosting.Weaver/IResolver.cs
@@ -1,45 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using Mono.Cecil;
-using System.Reflection;
-
-namespace DotWeb.Hosting.Weaver
-{
- public interface IGenericScope
- {
- Type ResolveGenericParameter(TypeReference typeRef);
- }
-
- public interface ITypeResolver
- {
- IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope);
- }
-
- public interface IAssembly : ITypeResolver
- {
- Assembly Assembly { get; }
- }
-
- public interface IResolver : ITypeResolver
- {
- MethodBase ResolveMethodReference(MethodReference methodRef, IGenericScope genericScope);
- FieldInfo ResolveFieldReference(FieldReference fieldRef, IGenericScope genericScope);
- }
-}
View
68 src/DotWeb.Hosting.Weaver/IType.cs
@@ -1,68 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Reflection;
-using Mono.Cecil;
-
-namespace DotWeb.Hosting.Weaver
-{
- public interface IType
- {
- Type Type { get; }
- MethodBase ResolveMethod(MethodReference methodRef);
- FieldInfo ResolveField(FieldDefinition fieldDef);
- void Close();
-
- void Process();
- }
-
- public class SimpleType : IType
- {
- private Type type;
-
- public SimpleType(Type type) {
- this.type = type;
- }
-
- #region IType Members
-
- public Type Type {
- get { return this.type; }
- }
-
- public MethodBase ResolveMethod(MethodReference methodRef) {
- throw new NotImplementedException();
- }
-
- public FieldInfo ResolveField(FieldDefinition fieldDef) {
- throw new NotImplementedException();
- }
-
- public void Close() {
- throw new NotImplementedException();
- }
-
- public void Process() {
- throw new NotImplementedException();
- }
-
- #endregion
- }
-
-}
View
437 src/DotWeb.Hosting.Weaver/MethodProcessor.cs
@@ -1,437 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Mono.Cecil;
-using System.Reflection.Emit;
-using Mono.Cecil.Cil;
-using System.Collections;
-using SR = System.Reflection;
-using SRE = System.Reflection.Emit;
-using System.Diagnostics;
-using DotWeb.Hosting;
-
-namespace DotWeb.Hosting.Weaver
-{
- class MethodProcessor : IGenericScope
- {
- private TypeProcessor parent;
- private IResolver resolver;
- private MethodDefinition methodDef;
- private MethodBase method;
- private Dictionary<Instruction, Label> labels = new Dictionary<Instruction, Label>();
- private Dictionary<VariableDefinition, LocalBuilder> locals = new Dictionary<VariableDefinition, LocalBuilder>();
- private GenericProcessor genericProc;
-
- public MethodProcessor(IResolver resolver, TypeProcessor parent, MethodDefinition methodDef) {
- this.resolver = resolver;
- this.parent = parent;
- this.methodDef = methodDef;
- this.genericProc = new GenericProcessor(this.resolver);
- }
-
- public void ProcessMethod(MethodBuilder methodBuilder) {
- Debug.Assert(this.method == null);
- this.method = methodBuilder;
-
- if (methodDef.HasGenericParameters) {
- this.genericProc.ProcessMethod(methodDef, methodBuilder);
- }
-
- var returnType = ResolveTypeReference(methodDef.ReturnType.ReturnType);
- methodBuilder.SetReturnType(returnType);
-
- if (methodDef.HasParameters) {
- var argTypes = ResolveParameterTypes(methodDef.Parameters);
- methodBuilder.SetParameters(argTypes);
-
- foreach (ParameterDefinition parameter in methodDef.Parameters) {
- methodBuilder.DefineParameter(parameter.Sequence, (SR.ParameterAttributes)parameter.Attributes, parameter.Name);
- }
- }
-
- if (methodDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, methodDef, methodBuilder, this);
- }
-
- methodBuilder.SetImplementationFlags((SR.MethodImplAttributes)methodDef.ImplAttributes);
-
- if (this.methodDef.HasBody) {
- Debug.Assert((methodBuilder.Attributes & SR.MethodAttributes.Abstract) == 0);
- var generator = methodBuilder.GetILGenerator();
- ProcessMethodBody(generator);
- }
- }
-
- public void ProcessConstructor(ConstructorBuilder ctorBuilder) {
- Debug.Assert(this.method == null);
- this.method = ctorBuilder;
-
- if (methodDef.HasGenericParameters) {
- throw new NotSupportedException();
- }
-
- if (methodDef.HasParameters) {
- foreach (ParameterDefinition parameter in methodDef.Parameters) {
- ctorBuilder.DefineParameter(parameter.Sequence, (SR.ParameterAttributes)parameter.Attributes, parameter.Name);
- }
- }
-
- if (methodDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, methodDef, ctorBuilder, this);
- }
-
- ctorBuilder.SetImplementationFlags((SR.MethodImplAttributes)methodDef.ImplAttributes);
-
- if (this.methodDef.HasBody) {
- var generator = ctorBuilder.GetILGenerator();
- ProcessMethodBody(generator);
- }
- }
-
- public void DeclareLocals(ILGenerator generator, VariableDefinitionCollection variables) {
- foreach (VariableDefinition variable in variables) {
- var type = ResolveTypeReference(variable.VariableType);
- var local = generator.DeclareLocal(type);
- local.SetLocalSymInfo(variable.Name);
-
- this.locals.Add(variable, local);
- }
- }
-
- private void DefineLabels(ILGenerator generator, InstructionCollection instructions) {
- foreach (Instruction cil in instructions) {
- if (cil.Operand is Instruction) {
- var key = (Instruction)cil.Operand;
- if (!labels.ContainsKey(key)) {
- var label = generator.DefineLabel();
- labels.Add(key, label);
- }
- }
- }
- }
-
- public void ProcessMethodBody(ILGenerator generator) {
- var body = methodDef.Body;
- if (body == null || body.CodeSize == 0) {
- GenerateExternMethodBody(generator);
- return;
- }
-
- DeclareLocals(generator, body.Variables);
-
- var scopeProc = new ScopeProcessor(this, generator);
- if (body.HasScopes)
- scopeProc.Push(body.Scopes);
-
- var exceptionProc = new ExceptionProcessor(this, generator);
- if (body.HasExceptionHandlers)
- exceptionProc.Start(body.ExceptionHandlers);
-
- DefineLabels(generator, body.Instructions);
-
- foreach (Instruction cil in body.Instructions) {
- if (body.HasScopes) {
- scopeProc.ProcessInstruction(cil);
- }
-
- if (body.HasExceptionHandlers) {
- exceptionProc.ProcessInstruction(cil);
- }
-
- Label label;
- if (labels.TryGetValue(cil, out label)) {
- generator.MarkLabel(label);
- }
-
- var point = cil.SequencePoint;
- if (point != null) {
- var doc = point.Document;
- var docWriter = this.parent.ModuleBuilder.DefineDocument(doc.Url, doc.Language, doc.LanguageVendor, doc.Type);
- generator.MarkSequencePoint(docWriter, point.StartLine, point.StartColumn, point.EndLine, point.EndColumn);
- }
-
- Emit(generator, cil);
- }
- }
-
- static class PredefinedTypes
- {
- public static readonly Type Arguments = typeof(object[]);
- public static readonly Type Object = typeof(object);
- public static readonly Type MethodBase = typeof(MethodBase);
- public static readonly Type IDotWebHost = typeof(IDotWebHost);
- public static readonly Type HostedMode = typeof(HostedMode);
-
- public static readonly MethodInfo HostedMode_get_Host;
- public static readonly MethodInfo IDotWebHost_Invoke;
- public static readonly MethodInfo IDotWebHost_Cast;
- public static readonly MethodInfo MethodBase_GetCurrentMethod;
- public static readonly ConstructorInfo Object_ctor;
-
- static PredefinedTypes() {
- HostedMode_get_Host = HostedMode.GetMethod("get_Host");
- IDotWebHost_Invoke = IDotWebHost.GetMethod("Invoke");
- IDotWebHost_Cast = IDotWebHost.GetMethod("Cast");
- MethodBase_GetCurrentMethod = MethodBase.GetMethod("GetCurrentMethod");
- Object_ctor = Object.GetConstructor(Type.EmptyTypes);
- }
- }
-
- public void GenerateExternMethodBody(ILGenerator generator) {
- bool needsReturn = (this.methodDef.ReturnType.ReturnType.FullName != Constants.Void);
-
- int indexOffset;
- if (this.methodDef.IsStatic)
- indexOffset = 0;
- else
- indexOffset = 1;
-
- var argCount = this.methodDef.Parameters.Count;
-
- var method = generator.DeclareLocal(PredefinedTypes.MethodBase);
- method.SetLocalSymInfo("__method");
-
- var args = generator.DeclareLocal(PredefinedTypes.Arguments);
- args.SetLocalSymInfo("__args");
-
- // constructors need to call their base class so that 'this' is initialized!
- // however, we don't want to call the real ctor, because it might not be setup at this time
- // also, the hosting bridge doesn't need to be called twice when calling the ctor on a dervied type.
- // thus, we'll just call the System.Object..ctor() instead, to appease .NET's reflection
- if (this.methodDef.IsConstructor) {
- generator.Emit(SRE.OpCodes.Ldarg_0);
- generator.Emit(SRE.OpCodes.Call, PredefinedTypes.Object_ctor);
- }
-
- // __method = MethodBase.GetCurrentMethod();
- generator.EmitCall(SRE.OpCodes.Call, PredefinedTypes.MethodBase_GetCurrentMethod, null);
- generator.Emit(SRE.OpCodes.Stloc, method.LocalIndex);
-
- LocalBuilder ret = null;
- if (needsReturn) {
- ret = generator.DeclareLocal(PredefinedTypes.Object);
- ret.SetLocalSymInfo("__ret");
- }
-
- // var args = new object[argCount];
- generator.Emit(SRE.OpCodes.Ldc_I4, argCount);
- generator.Emit(SRE.OpCodes.Newarr, PredefinedTypes.Object);
- generator.Emit(SRE.OpCodes.Stloc, args.LocalIndex);
-
- for (int i = 0; i < argCount; i++) {
- // __args[i] = <argument[i]>;
- generator.Emit(SRE.OpCodes.Ldloc, args.LocalIndex);
- generator.Emit(SRE.OpCodes.Ldc_I4, i);
- generator.Emit(SRE.OpCodes.Ldarg, i + indexOffset);
- var arg = this.methodDef.Parameters[i];
- if (arg.ParameterType.IsValueType) {
- var argType = Type.GetType(arg.ParameterType.FullName);
- generator.Emit(SRE.OpCodes.Box, argType);
- }
- generator.Emit(SRE.OpCodes.Stelem_Ref);
- }
-
- // __ret = HostedMode.Host.Invoke(this|null, __method, __args);
- generator.EmitCall(SRE.OpCodes.Call, PredefinedTypes.HostedMode_get_Host, null);
-
- if (this.methodDef.IsStatic)
- generator.Emit(SRE.OpCodes.Ldnull);
- else
- generator.Emit(SRE.OpCodes.Ldarg_0);
-
- generator.Emit(SRE.OpCodes.Ldloc, method.LocalIndex);
- generator.Emit(SRE.OpCodes.Ldloc, args.LocalIndex);
- generator.EmitCall(SRE.OpCodes.Callvirt, PredefinedTypes.IDotWebHost_Invoke, null);
-
- if (needsReturn) {
- // return __ret;
- generator.Emit(SRE.OpCodes.Stloc, ret.LocalIndex);
- generator.Emit(SRE.OpCodes.Ldloc, ret.LocalIndex);
-
- if (this.methodDef.ReturnType.ReturnType.IsValueType) {
- var methodInfo = (MethodInfo)this.method;
- generator.Emit(SRE.OpCodes.Unbox_Any, methodInfo.ReturnType);
- }
- }
- else {
- generator.Emit(SRE.OpCodes.Pop);
- }
-
- generator.Emit(SRE.OpCodes.Ret);
- }
-
- public void Emit(ILGenerator generator, Instruction cil) {
- SRE.OpCode code = OpCodeConverter.Convert(cil.OpCode);
- if (cil.Operand == null) {
- generator.Emit(code);
- return;
- }
-
- var typeName = cil.Operand.GetType().Name;
- switch (typeName) {
- case OperandTypeNames.Byte:
- generator.Emit(code, (byte)cil.Operand);
- break;
- case OperandTypeNames.SByte:
- generator.Emit(code, (sbyte)cil.Operand);
- break;
- case OperandTypeNames.Float:
- generator.Emit(code, (float)cil.Operand);
- break;
- case OperandTypeNames.Double:
- generator.Emit(code, (double)cil.Operand);
- break;
- case OperandTypeNames.Short:
- generator.Emit(code, (short)cil.Operand);
- break;
- case OperandTypeNames.Int:
- generator.Emit(code, (int)cil.Operand);
- break;
- case OperandTypeNames.Long:
- generator.Emit(code, (long)cil.Operand);
- break;
- case OperandTypeNames.String:
- generator.Emit(code, (string)cil.Operand);
- break;
- case OperandTypeNames.MethodReference:
- case OperandTypeNames.MethodDefinition:
- EmitMethod(generator, code, (MethodReference)cil.Operand);
- break;
- case OperandTypeNames.TypeReference:
- case OperandTypeNames.TypeDefinition:
- EmitType(generator, code, (TypeReference)cil.Operand);
- break;
- case OperandTypeNames.FieldReference:
- case OperandTypeNames.FieldDefinition:
- EmitField(generator, code, (FieldReference)cil.Operand);
- break;
- case OperandTypeNames.Instruction:
- generator.Emit(code, labels[(Instruction)cil.Operand]);
- break;
- case OperandTypeNames.VariableDefinition:
- generator.Emit(code, locals[(VariableDefinition)cil.Operand]);
- break;
- case OperandTypeNames.ParameterDefinition:
- EmitParameter(generator, code, (ParameterDefinition)cil.Operand);
- break;
- case OperandTypeNames.GenericParameter:
- EmitParameter(generator, code, (GenericParameter)cil.Operand);
- break;
- case OperandTypeNames.GenericInstanceMethod:
- EmitGenericInstanceMethod(generator, code, (GenericInstanceMethod)cil.Operand);
- break;
- default:
- throw new NotSupportedException(string.Format("OperandType: {0}", typeName));
- }
- }
-
- private void EmitGenericInstanceMethod(ILGenerator generator, SRE.OpCode code, GenericInstanceMethod genericInstanceMethod) {
- var methodBase = this.resolver.ResolveMethodReference(genericInstanceMethod, this);
- if (methodBase is ConstructorInfo) {
- var ctorInfo = (ConstructorInfo)methodBase;
- generator.Emit(code, ctorInfo);
- }
- else {
- var genericArgumentRefs = genericInstanceMethod.GenericArguments.Cast<TypeReference>();
- var typeArguments = genericArgumentRefs.Select(x => ResolveTypeReference(x)).ToArray();
- var genericMethod = (MethodInfo)methodBase;
- var concreteMethod = genericMethod.MakeGenericMethod(typeArguments);
- generator.Emit(code, concreteMethod);
- }
- }
-
- private void EmitParameter(ILGenerator generator, SRE.OpCode code, GenericParameter genericParamater) {
- var type = ResolveTypeReference(genericParamater);
- generator.Emit(code, type);
- }
-
- private void EmitParameter(ILGenerator generator, SRE.OpCode code, ParameterDefinition parameterDef) {
- generator.Emit(code, parameterDef.Sequence);
- }
-
- public void EmitMethod(ILGenerator generator, SRE.OpCode code, MethodReference methodRef) {
- var methodBase = this.resolver.ResolveMethodReference(methodRef, this);
- if (methodBase is ConstructorInfo)
- generator.Emit(code, (ConstructorInfo)methodBase);
- else
- generator.Emit(code, (MethodInfo)methodBase);
- }
-
- public void EmitType(ILGenerator generator, SRE.OpCode code, TypeReference typeRef) {
- var type = ResolveTypeReference(typeRef);
- if (code == SRE.OpCodes.Castclass) {
- var cast = generator.DeclareLocal(PredefinedTypes.Object);
- generator.Emit(SRE.OpCodes.Stloc, cast.LocalIndex);
-
- generator.EmitCall(SRE.OpCodes.Call, PredefinedTypes.HostedMode_get_Host, null);
-
- generator.Emit(SRE.OpCodes.Ldloc, cast.LocalIndex);
- var castCall = PredefinedTypes.IDotWebHost_Cast.MakeGenericMethod(type);
- generator.EmitCall(SRE.OpCodes.Callvirt, castCall, null);
- }
- else if (code == SRE.OpCodes.Isinst) {
- }
- else {
- generator.Emit(code, type);
- }
- }
-
- public void EmitField(ILGenerator generator, SRE.OpCode code, FieldReference fieldRef) {
- var field = this.resolver.ResolveFieldReference(fieldRef, this);
- generator.Emit(code, field);
- }
-
- public Type ResolveTypeReference(TypeReference typeRef) {
- var arrayType = typeRef as ArrayType;
- if (typeRef is GenericParameter ||
- (arrayType != null && arrayType.ElementType is GenericParameter)) {
- // deals with T[] also
- return ResolveGenericParameter(typeRef);
- }
-
- return this.resolver.ResolveTypeReference(typeRef, this).Type;
- }
-
- private Type[] ResolveParameterTypes(ParameterDefinitionCollection parameters) {
- Type[] ret = new Type[parameters.Count];
- for (int i = 0; i < parameters.Count; i++) {
- var arg = parameters[i];
- var argType = arg.ParameterType;
- ret[i] = ResolveTypeReference(argType);
- }
- return ret;
- }
-
-
- #region IGenericScope Members
-
- public Type ResolveGenericParameter(TypeReference typeRef) {
- var arg = this.genericProc.ResolveGenericParameter(typeRef);
- if (arg != null)
- return arg;
- return this.parent.GetGenericParameter(typeRef);
- }
-
- #endregion
- }
-}
View
73 src/DotWeb.Hosting.Weaver/OpCodeConverter.cs
@@ -1,73 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-
-using CecilOpCode = Mono.Cecil.Cil.OpCode;
-using CecilOpCodes = Mono.Cecil.Cil.OpCodes;
-
-using SysOpCode = System.Reflection.Emit.OpCode;
-using SysOpCodes = System.Reflection.Emit.OpCodes;
-
-namespace DotWeb.Hosting.Weaver
-{
- class OperandTypeNames
- {
- public const string Byte = "Byte";
- public const string SByte = "SByte";
- public const string Double = "Double";
- public const string Float = "Single";
- public const string Int = "Int32";
- public const string Short = "Int16";
- public const string Long = "Int64";
- public const string String = "String";
- public const string MethodReference = "MethodReference";
- public const string MethodDefinition = "MethodDefinition";
- public const string FieldReference = "FieldReference";
- public const string FieldDefinition = "FieldDefinition";
- public const string TypeReference = "TypeReference";
- public const string TypeDefinition = "TypeDefinition";
- public const string VariableDefinition = "VariableDefinition";
- public const string ParameterDefinition = "ParameterDefinition";
- public const string GenericParameter = "GenericParameter";
- public const string GenericInstanceMethod = "GenericInstanceMethod";
- public const string Instruction = "Instruction";
- }
-
- class OpCodeConverter
- {
- static Dictionary<short, SysOpCode> dict = new Dictionary<short, SysOpCode>();
- static OpCodeConverter() {
- var type = typeof(SysOpCodes);
- var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
- foreach (var field in fields) {
- SysOpCode code = (SysOpCode)field.GetValue(null);
- dict.Add(code.Value, code);
- }
- }
-
- public static SysOpCode Convert(CecilOpCode src) {
- return dict[src.Value];
- }
- }
-
-}
View
68 src/DotWeb.Hosting.Weaver/ScopeProcessor.cs
@@ -1,68 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection.Emit;
-using Mono.Cecil.Cil;
-using System.Collections;
-
-namespace DotWeb.Hosting.Weaver
-{
- class ScopeProcessor
- {
- private MethodProcessor parent;
- private ILGenerator generator;
- private Scope nextScope = null;
- private Scope curScope = null;
- private IEnumerator itScopes = null;
-
- public ScopeProcessor(MethodProcessor parent, ILGenerator generator) {
- this.parent = parent;
- this.generator = generator;
- }
-
- public void Push(ScopeCollection scopes) {
- itScopes = scopes.GetEnumerator();
- nextScope = Next();
- }
-
- private Scope Next() {
- return itScopes.MoveNext() ? (Scope)itScopes.Current : null;
- }
-
- public void ProcessInstruction(Instruction cil) {
- if (nextScope != null && cil.Offset >= nextScope.Start.Offset) {
- curScope = nextScope;
- nextScope = Next();
-
- generator.BeginScope();
-
- parent.DeclareLocals(generator, curScope.Variables);
- }
-
- if (curScope != null && cil.Offset >= curScope.End.Offset) {
- curScope = null;
-
- generator.EndScope();
- }
- }
- }
-}
View
113 src/DotWeb.Hosting.Weaver/SimpleWeaver.cs
@@ -26,13 +26,10 @@ public class SimpleWeaver
{
class ConstantNames
{
- public const string DotWebSystem = "DotWeb.System";
- public const string DotWebSystemDll = "DotWeb.System.dll";
public const string Mscorlib = "mscorlib";
public const string SystemCore = "System.Core";
- public const string SystemCoreDll = "System.Core.dll";
- public const string AssemblyWeavedAttribute = "AssemblyWeavedAttribute";
- public const string CommonLanguageRuntimeLibrary = "CommonLanguageRuntimeLibrary";
+ public const string DotWebCoreLib = "DotWebCoreLib";
+ public const string HostedPrefix = "Hosted-";
}
private bool forceBuild;
@@ -56,46 +53,62 @@ class ConstantNames
public SR.Assembly ProcessAssembly(string asmPath) {
var asmDef = this.resolver.GetAssembly(asmPath, true);
- foreach (var item in asmDef.CustomAttributes) {
- if (item.Constructor.DeclaringType.Name == ConstantNames.AssemblyWeavedAttribute) {
- Console.WriteLine("This assembly has already been weaved and is ready for hosted mode");
- return SR.Assembly.LoadFrom(asmPath);
- }
- }
var visited = new HashSet<string>();
- visited.Add("mscorlib");
- visited.Add("System.Core");
- visited.Add("DotWebCoreLib");
+ visited.Add(ConstantNames.Mscorlib);
+ visited.Add(ConstantNames.SystemCore);
+ visited.Add(ConstantNames.DotWebCoreLib);
- var path = ProcessAssembly(asmDef, visited);
- return SR.Assembly.LoadFrom(path);
- }
+ var tasks = new List<AssemblyDefinition>();
+ GetTaskList(asmDef, visited, tasks);
+
+ foreach (var task in tasks) {
+ ProcessAssembly(task);
+ }
- const string HostedPrefix = "Hosted-";
+ var outputPath = HostedPath(asmDef.Name);
+ return SR.Assembly.LoadFrom(outputPath);
+ }
- private string ProcessAssembly(AssemblyDefinition asmDef, HashSet<string> visited) {
- var asmRefs = asmDef.MainModule.AssemblyReferences;
- foreach (var asmRef in asmRefs.Originals(visited, x => x.Name)) {
- var child = this.resolver.Resolve(asmRef);
- ProcessAssembly(child, visited);
+ private string HostedName(AssemblyNameReference asmRef) {
+ if (!asmRef.Name.StartsWith(ConstantNames.HostedPrefix)) {
+ return ConstantNames.HostedPrefix + asmRef.Name;
}
+ return asmRef.Name;
+ }
- foreach (var asmRef in asmRefs) {
- if (asmRef.Name == "mscorlib" || asmRef.Name == "System.Core")
- continue;
- if (asmRef.Name == "DotWebCoreLib") {
- ReplaceAssemblyReference(asmRef, asmRefMscorlib);
- }
- else {
- var name = asmRef.Name;
- if (!name.StartsWith(HostedPrefix)) {
- name = HostedPrefix + name;
- asmRef.Name = name;
- }
- }
+ private string InputPath(AssemblyNameReference asmRef) {
+ return Path.Combine(this.inputDir, MakeAssemblyNameIntoFilename(asmRef.Name));
+ }
+
+ private string HostedPath(AssemblyNameReference asmRef) {
+ var hostedName = HostedName(asmRef);
+ return Path.Combine(this.outputDir, MakeAssemblyNameIntoFilename(hostedName));
+ }
+
+ private bool NeedsProcessing(AssemblyNameReference asmRef) {
+ var inputPath = InputPath(asmRef);
+ var outputPath = HostedPath(asmRef);
+ if (!this.forceBuild &&
+ File.Exists(outputPath) &&
+ File.GetLastWriteTime(inputPath) < File.GetLastWriteTime(outputPath))
+ return false;
+ return true;
+ }
+
+ private void GetTaskList(AssemblyDefinition asmDef, HashSet<string> visited, List<AssemblyDefinition> tasks) {
+ foreach (var asmRef in asmDef.MainModule.AssemblyReferences.Originals(visited, x => x.Name)) {
+ var dependency = this.resolver.Resolve(asmRef);
+ GetTaskList(dependency, visited, tasks);
}
+ if(NeedsProcessing(asmDef.Name))
+ tasks.Add(asmDef);
+ }
+
+ private string ProcessAssembly(AssemblyDefinition asmDef) {
+ RedirectAssemblyReferences(asmDef);
+
var templates = PrepareTemplates(asmDef.MainModule);
foreach (var typeDef in asmDef.MainModule.Types) {
ProcessType(typeDef, templates);
@@ -104,6 +117,19 @@ class ConstantNames
return SaveAssembly(asmDef);
}
+ private void RedirectAssemblyReferences(AssemblyDefinition asmDef) {
+ foreach (var asmRef in asmDef.MainModule.AssemblyReferences) {
+ if (asmRef.Name == ConstantNames.Mscorlib || asmRef.Name == ConstantNames.SystemCore)
+ continue;
+ if (asmRef.Name == ConstantNames.DotWebCoreLib) {
+ ReplaceAssemblyReference(asmRef, asmRefMscorlib);
+ }
+ else {
+ asmRef.Name = HostedName(asmRef);
+ }
+ }
+ }
+
private void ReplaceAssemblyReference(AssemblyNameReference lhs, AssemblyNameReference rhs) {
lhs.Name = rhs.Name;
lhs.Version = rhs.Version;
@@ -127,18 +153,15 @@ class ConstantNames
}
private string SaveAssembly(AssemblyDefinition asmDef) {
- string name = asmDef.Name.Name;
- if (!name.StartsWith(HostedPrefix)) {
- name = HostedPrefix + name;
- asmDef.Name.Name = name;
- asmDef.MainModule.Name = name;
- }
+ var name = HostedName(asmDef.Name);
+ asmDef.Name.Name = name;
+ asmDef.MainModule.Name = name;
- string path = Path.Combine(this.outputDir, MakeAssemblyNameIntoFilename(name));
- asmDef.Write(path, new WriterParameters {
+ var outputPath = HostedPath(asmDef.Name);
+ asmDef.Write(outputPath, new WriterParameters {
SymbolWriterProvider = AssemblyResolver.GetPlatformWriterProvider()
});
- return path;
+ return outputPath;
}
private string MakeAssemblyNameIntoFilename(string name) {
View
378 src/DotWeb.Hosting.Weaver/TypeProcessor.cs
@@ -1,378 +0,0 @@
-// Copyright 2009, Frank Laub
-//
-// This file is part of DotWeb.
-//
-// DotWeb is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DotWeb is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with DotWeb. If not, see <http://www.gnu.org/licenses/>.
-//
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-using SR = System.Reflection;
-using SRE = System.Reflection.Emit;
-using System.Collections;
-using Mono.Cecil.Metadata;
-
-namespace DotWeb.Hosting.Weaver
-{
- class TypeProcessor : IType
- {
- public Type Type { get { return this.typeBuilder; } }
- public ModuleBuilder ModuleBuilder { get; private set; }
-
- private TypeDefinition typeDef;
- private AssemblyProcessor parent;
- private TypeBuilder typeBuilder;
- private Dictionary<MetadataToken, MethodBase> methods = new Dictionary<MetadataToken, MethodBase>();
- private Dictionary<FieldDefinition, FieldBuilder> fields = new Dictionary<FieldDefinition, FieldBuilder>();
- private IResolver resolver;
- private GenericProcessor genericProc;
- private bool isClosing = false;
- private bool isProcessed = false;
- private HashSet<TypeProcessor> dependentTypes = new HashSet<TypeProcessor>();
- private List<IType> nestedTypes = new List<IType>();
-
- class DependentTypeResolver : ITypeResolver
- {
- TypeProcessor typeProc;
-
- public DependentTypeResolver(TypeProcessor typeProc) {
- this.typeProc = typeProc;
- }
-
- public IType ResolveTypeReference(TypeReference typeRef, IGenericScope genericScope) {
- return this.typeProc.ResolveTypeReferenceToProc(typeRef, true);
- }
- }
-
- public TypeProcessor(IResolver resolver, AssemblyProcessor parent, TypeDefinition typeDef, ModuleBuilder moduleBuilder, TypeBuilder outerBuilder) {
- this.resolver = resolver;
- this.parent = parent;
- this.typeDef = typeDef;
- this.ModuleBuilder = moduleBuilder;
-
- var dtr = new DependentTypeResolver(this);
- this.genericProc = new GenericProcessor(dtr);
-
- var typeAttrs = (SR.TypeAttributes)this.typeDef.Attributes;
- if (outerBuilder == null) {
- this.typeBuilder = moduleBuilder.DefineType(this.typeDef.FullName, typeAttrs);
- }
- else {
- this.typeBuilder = outerBuilder.DefineNestedType(this.typeDef.Name, typeAttrs);
- }
-
- if (this.typeDef.HasGenericParameters) {
- this.genericProc.ProcessType(typeDef, typeBuilder);
- }
-
- if (this.typeDef.BaseType != null) {
- var baseType = ResolveTypeReference(typeDef.BaseType, true);
- this.typeBuilder.SetParent(baseType);
- }
-
- foreach (TypeReference item in this.typeDef.Interfaces) {
- var type = ResolveTypeReference(item, true);
- this.typeBuilder.AddInterfaceImplementation(type);
- }
- }
-
- public override string ToString() {
- return string.Format("TypeProcessor: {0}", this.typeBuilder.ToString());
- }
-
- public void Close() {
- if (this.isClosing)
- return;
-
- this.isClosing = true;
-
- foreach (var type in dependentTypes) {
- type.Close();
- }
-
- // This is super super slow thanks to:
- // http://support.microsoft.com/kb/970924
- this.typeBuilder.CreateType();
-
- foreach (var type in nestedTypes) {
- type.Close();
- }
- }
-
- public Type GetGenericParameter(TypeReference typeRef) {
- return this.genericProc.ResolveGenericParameter(typeRef);
- }
-
- public void Process() {
- if (this.isProcessed)
- return;
-
- this.isProcessed = true;
-
- if (this.typeDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, this.typeDef, this.typeBuilder, this.genericProc);
- }
-
- foreach (FieldDefinition item in this.typeDef.Fields) {
- if (!this.fields.ContainsKey(item))
- ProcessField(item);
- }
-
- foreach (MethodDefinition item in this.typeDef.Constructors) {
- if (!this.methods.ContainsKey(item.MetadataToken))
- ProcessConstructor(item);
- }
-
- foreach (MethodDefinition item in this.typeDef.Methods) {
- if (!this.methods.ContainsKey(item.MetadataToken))
- ProcessMethod(item);
- }
-
- foreach (EventDefinition item in this.typeDef.Events) {
- ProcessEvent(item);
- }
-
- foreach (PropertyDefinition item in this.typeDef.Properties) {
- ProcessProperty(item);
- }
-
- foreach (TypeDefinition item in this.typeDef.NestedTypes) {
- ProcessNestedType(item);
- }
- }
-
- private void ProcessNestedType(TypeDefinition typeDef) {
- if (typeDef.Name.StartsWith("__StaticArrayInitTypeSize=")) {
- return;
- }
-
- var nestedType = this.resolver.ResolveTypeReference(typeDef, this.genericProc);
- this.nestedTypes.Add(nestedType);
- }
-
- private void ProcessEvent(EventDefinition eventDef) {
- var eventType = ResolveTypeReference(eventDef.EventType, false);
- var eventBuilder = this.typeBuilder.DefineEvent(eventDef.Name, (SR.EventAttributes)eventDef.Attributes, eventType);
-
- if (eventDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, eventDef, eventBuilder, this.genericProc);
- }
-
- if (eventDef.AddMethod != null) {
- var method = (MethodBuilder)this.resolver.ResolveMethodReference(eventDef.AddMethod, this.genericProc);
- eventBuilder.SetAddOnMethod(method);
- }
-
- if (eventDef.RemoveMethod != null) {
- var method = (MethodBuilder)this.resolver.ResolveMethodReference(eventDef.RemoveMethod, this.genericProc);
- eventBuilder.SetRemoveOnMethod(method);
- }
- }
-
- private FieldBuilder ProcessField(FieldDefinition fieldDef) {
- FieldBuilder fieldBuilder;
- if (fieldDef.InitialValue != null && fieldDef.InitialValue.Length > 0) {
- fieldBuilder = this.typeBuilder.DefineInitializedData(
- fieldDef.Name,
- fieldDef.InitialValue,
- (SR.FieldAttributes)fieldDef.Attributes);
- }
- else {
- var fieldType = ResolveTypeReference(fieldDef.FieldType, false);
- fieldBuilder = this.typeBuilder.DefineField(fieldDef.Name, fieldType, (SR.FieldAttributes)fieldDef.Attributes);
- }
-
- if (fieldDef.HasConstant) {
- // FIXME: Not sure what this was doing here! I have not found a suitable test to make things break without it.
- //if (fieldType.IsEnum) {
- // object value = Enum.ToObject(fieldType, fieldDef.Constant);
- // fieldBuilder.SetConstant(value);
- //}
- //else {
- fieldBuilder.SetConstant(fieldDef.Constant);
- //}
- }
-
- if (fieldDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, fieldDef, fieldBuilder, this.genericProc);
- }
-
- RegisterField(fieldDef, fieldBuilder);
-
- return fieldBuilder;
- }
-
- private void ProcessProperty(PropertyDefinition propertyDef) {
- var returnType = ResolveTypeReference(propertyDef.PropertyType, false);
- var argTypes = ResolveParameterTypes(propertyDef.Parameters);
- var propertyBuilder = this.typeBuilder.DefineProperty(propertyDef.Name, (SR.PropertyAttributes)propertyDef.Attributes, returnType, argTypes);
-
- if (propertyDef.HasConstant) {
- propertyBuilder.SetConstant(propertyDef.Constant);
- }
-
- if (propertyDef.HasCustomAttributes) {
- CustomAttributeProcessor.Process(this.resolver, propertyDef, propertyBuilder, this.genericProc);
- }
-
- if (propertyDef.GetMethod != null) {
- var method = this.resolver.ResolveMethodReference(propertyDef.GetMethod, this.genericProc);
- propertyBuilder.SetGetMethod((MethodBuilder)method);
- }
-
- if (propertyDef.SetMethod != null) {
- var method = this.resolver.ResolveMethodReference(propertyDef.SetMethod, this.genericProc);
- propertyBuilder.SetSetMethod((MethodBuilder)method);
- }
- }
-
- public ConstructorInfo ProcessConstructor(MethodDefinition methodDef) {
- var realMethodDef = GetRedirectedMethod(methodDef);
- var argTypes = ResolveParameterTypes(realMethodDef.Parameters);
- var ctorBuilder = this.typeBuilder.DefineConstructor(
- (SR.MethodAttributes)realMethodDef.Attributes,
- (SR.CallingConventions)realMethodDef.CallingConvention,
- argTypes);
-
- // register this before processing the body to deal with circular or recursive references
- RegisterMethod(methodDef, ctorBuilder);
-
- var methodProc = new MethodProcessor(this.resolver, this, realMethodDef);
- methodProc.ProcessConstructor(ctorBuilder);
- return ctorBuilder;
- }
-
- public MethodBase ProcessMethod(MethodDefinition methodDef) {
- if (methodDef.IsConstructor)
- return ProcessConstructor(methodDef);
-
- var realMethodDef = GetRedirectedMethod(methodDef);
- var methodAttrs = (SR.MethodAttributes)realMethodDef.Attributes;
-
- var methodBuilder = this.typeBuilder.DefineMethod(realMethodDef.Name, methodAttrs);
-
- // insert this before processing the body to deal with circular or recursive references
- RegisterMethod(methodDef, methodBuilder);
-
- <