Permalink
Browse files

When casting to an int, use Math.floor() in order to simulate the imp…

…licit conversion that would happen in .NET
  • Loading branch information...
1 parent ab1e4c5 commit 4797344316e6aca1df9202b5e90539213bf81d97 Frank Laub committed Mar 6, 2010
Showing with 1,689 additions and 476 deletions.
  1. +0 −5 src/DotWeb.Decompiler/CodeModel/Member/CodeMethodMember.cs
  2. +52 −0 src/DotWeb.Decompiler/CodeModel/Member/CodeTypeInitializer.cs
  3. +39 −6 src/DotWeb.Decompiler/CodeTypeEvaluator.cs
  4. +4 −0 src/DotWeb.Decompiler/Core/Interpreter.cs
  5. +1 −0 src/DotWeb.Decompiler/DotWeb.Decompiler.csproj
  6. +34 −15 src/DotWeb.Decompiler/MethodDecompiler.cs
  7. +39 −19 src/DotWeb.System/Array.cs
  8. +223 −2 src/DotWeb.System/Collections/Generic/Dictionary.cs
  9. +0 −257 src/DotWeb.System/Collections/Hashtable.cs
  10. +3 −0 src/DotWeb.System/Console.cs
  11. +0 −1 src/DotWeb.System/DotWeb.System.csproj
  12. +40 −17 src/DotWeb.System/Exception.cs
  13. +0 −1 src/DotWeb.System/Hosted-DotWeb.System.csproj
  14. +42 −0 src/DotWeb.Translator/Generator/JavaScript/JsCodeGenerator.cs
  15. +17 −11 src/DotWeb.Translator/Generator/JavaScript/JsPrinter.cs
  16. +7 −0 src/DotWeb.Translator/TranslationContext.cs
  17. +3 −2 src/DotWeb.Utility/Cecil/TypeDefinitionCache.cs
  18. +1 −1 test/DotWeb.Functional.Test/Client/ArrayTest.cs
  19. +8 −8 test/DotWeb.Functional.Test/Client/{HashtableTest.cs → DictionaryTest.cs}
  20. +2 −2 test/DotWeb.Functional.Test/Client/DotWeb.Functional.Test.Client.csproj
  21. +21 −21 test/DotWeb.Functional.Test/Client/{List.cs → ListTest.cs}
  22. +6 −6 test/DotWeb.Functional.Test/Client/StringBuilderTest.cs
  23. +26 −26 test/DotWeb.Functional.Test/Client/StringTest.cs
  24. +4 −2 test/DotWeb.Functional.Test/Client/TestResultView.cs
  25. +2 −2 test/DotWeb.Functional.Test/Server/App_Data/TestDirectory.txt
  26. +1 −0 test/DotWeb.Translator.Test/DotWeb.Translator.Test.csproj
  27. +2 −2 test/DotWeb.Translator.Test/Expected/DecorationTest/TestJsIntrinsic.js
  28. +451 −2 test/DotWeb.Translator.Test/Expected/GeneralTests/Debug/ArgumentException.js
  29. +4 −0 test/DotWeb.Translator.Test/Expected/GeneralTests/Debug/CallDerived.js
  30. +5 −5 test/DotWeb.Translator.Test/Expected/GeneralTests/Debug/Callback.js
  31. +12 −12 test/DotWeb.Translator.Test/Expected/GeneralTests/Debug/ExpectExceptionTest.js
  32. +451 −2 test/DotWeb.Translator.Test/Expected/GeneralTests/Release/ArgumentException.js
  33. +4 −0 test/DotWeb.Translator.Test/Expected/GeneralTests/Release/CallDerived.js
  34. +5 −5 test/DotWeb.Translator.Test/Expected/GeneralTests/Release/Callback.js
  35. +12 −12 test/DotWeb.Translator.Test/Expected/GeneralTests/Release/ExpectExceptionTest.js
  36. +45 −8 test/DotWeb.Translator.Test/Expected/GeneralTests/Release/StringFormat.js
  37. +29 −0 test/DotWeb.Translator.Test/Expected/SystemTest/TestCastPrimitive.js
  38. +12 −12 test/DotWeb.Translator.Test/Expected/SystemTest/TestListEnumerator.js
  39. +16 −12 test/DotWeb.Translator.Test/Expected/SystemTest/TestString.js
  40. +26 −0 test/DotWeb.Translator.Test/Resources/SystemTestData.Designer.cs
  41. +3 −0 test/DotWeb.Translator.Test/Resources/SystemTestData.resx
  42. +34 −0 test/DotWeb.Translator.Test/Script/SystemTest.cs
  43. +3 −0 test/DotWeb.Translator.Test/SystemTest.cs
@@ -59,10 +59,5 @@ public CodeMethodMember(MethodDefinition method)
public List<CodeParameterDeclarationExpression> Parameters { get; set; }
public HashSet<MethodReference> ExternalMethods { get; set; }
public string NativeCode { get; set; }
-
- /// <summary>
- /// Used for debugging purposes
- /// </summary>
- //public IEnumerable<Instruction> Instructions { get; set; }
}
}
@@ -0,0 +1,52 @@
+// Copyright 2010, 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 DotWeb.Decompiler.Core;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+namespace DotWeb.Decompiler.CodeModel
+{
+ public class CodeTypeInitializer : CodeMethodMember
+ {
+ public CodeTypeInitializer(CodeMethodMember method) {
+ this.Definition = method.Definition;
+ this.Statements = method.Statements;
+ this.Parameters = method.Parameters;
+ this.ExternalMethods = method.ExternalMethods;
+ this.NativeCode = method.NativeCode;
+ this.DefaultStaticFields = new List<FieldDefinition>();
+ }
+
+ #region Visitor Pattern
+ public override void Accept<V>(V visitor) {
+ ((ICodeVisitor<CodeTypeInitializer>)visitor).Visit(this);
+ }
+
+ public override R Accept<V, R>(V visitor) {
+ return ((ICodeVisitor<CodeTypeInitializer, R>)visitor).VisitReturn(this);
+ }
+ #endregion
+
+ public List<FieldDefinition> DefaultStaticFields { get; set; }
+ }
+}
@@ -59,24 +59,57 @@ public class CodeTypeEvaluator : ICodeExpressionVisitor<TypeReference>
case CodeBinaryOperator.LessThanOrEqual:
case CodeBinaryOperator.ValueEquality:
return this.typeSystem.TypeDefinitionCache.Boolean;
- case CodeBinaryOperator.Add:
case CodeBinaryOperator.BitwiseAnd:
case CodeBinaryOperator.BitwiseOr:
- case CodeBinaryOperator.Divide:
case CodeBinaryOperator.ExclusiveOr:
case CodeBinaryOperator.LeftShift:
case CodeBinaryOperator.Modulus:
- case CodeBinaryOperator.Multiply:
case CodeBinaryOperator.RightShift:
- case CodeBinaryOperator.Subtract:
case CodeBinaryOperator.UnsignedRightShift:
- // FIXME: find 'highest' type of each side
return Evaluate(obj.Left);
+ case CodeBinaryOperator.Add:
+ case CodeBinaryOperator.Subtract:
+ case CodeBinaryOperator.Multiply:
+ case CodeBinaryOperator.Divide:
+ return SelectType(obj.Left, obj.Right);
default:
throw new NotSupportedException();
}
}
+ private int GetTypeScore(TypeReference type) {
+ switch (type.FullName) {
+ case Constants.Byte:
+ case Constants.SByte:
+ case Constants.Char:
+ return 1;
+ case Constants.Int16:
+ case Constants.UInt16:
+ return 2;
+ case Constants.Int32:
+ case Constants.UInt32:
+ return 3;
+ case Constants.Int64:
+ case Constants.UInt64:
+ return 4;
+ case Constants.Single:
+ return 5;
+ case Constants.Double:
+ return 6;
+ }
+ return 0;
+ }
+
+ private TypeReference SelectType(CodeExpression lhs, CodeExpression rhs) {
+ var lhsType = Evaluate(lhs);
+ var rhsType = Evaluate(rhs);
+
+ int lhsScore = GetTypeScore(lhsType);
+ int rhsScore = GetTypeScore(rhsType);
+
+ return lhsScore > rhsScore ? lhsType : rhsType;
+ }
+
public TypeReference VisitReturn(CodeCastExpression obj) {
return obj.TargetType;
}
@@ -124,7 +157,7 @@ public class CodeTypeEvaluator : ICodeExpressionVisitor<TypeReference>
}
public TypeReference VisitReturn(CodeLengthReference obj) {
- throw new NotSupportedException();
+ return this.typeSystem.TypeDefinitionCache.Int32;
}
public TypeReference VisitReturn(CodeMethodReference obj) {
@@ -38,9 +38,11 @@ public class Interpreter
private CodeTypeEvaluator typeEvaluator;
public HashSet<MethodReference> ExternalMethods { get; private set; }
+ public HashSet<FieldDefinition> StaticFieldsSet { get; private set; }
public Interpreter(TypeSystem typeSystem, MethodDefinition method) {
this.ExternalMethods = new HashSet<MethodReference>();
+ this.StaticFieldsSet = new HashSet<FieldDefinition>();
this.typeSystem = typeSystem;
this.method = method;
this.typeEvaluator = new CodeTypeEvaluator(this.typeSystem, this.method);
@@ -773,6 +775,8 @@ public class Interpreter
var typeRef = new CodeTypeReference(field.DeclaringType);
var lhs = new CodeFieldReference(typeRef, field);
AddAssignment(lhs, rhs);
+
+ this.StaticFieldsSet.Add(field.Resolve());
}
private void BinaryExpression(Instruction il, CodeBinaryOperator op) {
@@ -85,6 +85,7 @@
<Compile Include="CodeModel\Member\CodePropertySetterMember.cs" />
<Compile Include="CodeModel\Member\CodeTypeDeclaration.cs" />
<Compile Include="CodeModel\Member\CodeTypeMember.cs" />
+ <Compile Include="CodeModel\Member\CodeTypeInitializer.cs" />
<Compile Include="CodeModel\Member\ICodeMemberVisitor.cs" />
<Compile Include="CodeModel\Statement\CodeAssignStatement.cs" />
<Compile Include="CodeModel\Statement\CodeCommentStatement.cs" />
@@ -28,6 +28,40 @@ namespace DotWeb.Decompiler
public static class MethodDecompiler
{
public static CodeMethodMember Parse(TypeSystem typeSystem, MethodDefinition method) {
+ var interpreter = new Interpreter(typeSystem, method);
+ var ret = ParseMethod(method, typeSystem, interpreter);
+ var ap = method.GetMonoAssociatedProperty();
+ if (ap != null) {
+ if (ap.IsGetter) {
+ return new CodePropertyGetterMember(ret) {
+ Property = ap.Definition
+ };
+ }
+
+ return new CodePropertySetterMember(ret) {
+ Property = ap.Definition
+ };
+ }
+ return ret;
+ }
+
+ public static CodeTypeInitializer ParseStaticConstructor(TypeSystem typeSystem, MethodDefinition method) {
+ var interpreter = new Interpreter(typeSystem, method);
+ var methodMember = ParseMethod(method, typeSystem, interpreter);
+ var typeInitializer = new CodeTypeInitializer(methodMember);
+
+ var type = method.DeclaringType;
+ foreach (FieldDefinition field in type.Fields) {
+ if (field.IsStatic && !interpreter.StaticFieldsSet.Contains(field)) {
+ // create default initializer
+ typeInitializer.DefaultStaticFields.Add(field);
+ }
+ }
+
+ return typeInitializer;
+ }
+
+ private static CodeMethodMember ParseMethod(MethodDefinition method, TypeSystem typeSystem, Interpreter interpreter) {
#if DEBUG
Console.WriteLine(method);
#endif
@@ -41,7 +75,6 @@ public static class MethodDecompiler
graph.SortByDepthFirstPostOrder();
- var interpreter = new Interpreter(typeSystem, method);
foreach (BasicBlock block in graph.Nodes) {
interpreter.ProcessBlock(block);
}
@@ -55,20 +88,6 @@ public static class MethodDecompiler
var generator = new StatementsGenerator(method, graph);
var ret = generator.WriteMethodBody();
ret.ExternalMethods = interpreter.ExternalMethods;
-
- var ap = method.GetMonoAssociatedProperty();
- if (ap != null) {
- if (ap.IsGetter) {
- return new CodePropertyGetterMember(ret) {
- Property = ap.Definition
- };
- }
-
- return new CodePropertySetterMember(ret) {
- Property = ap.Definition
- };
- }
-
return ret;
}
}
View
@@ -36,25 +36,45 @@ public class Array : JsObject
public extern object this[int index] { get; set; }
#if !HOSTED_MODE
- ///// <summary>
- ///// Copies a range of elements from an Array starting at the specified source index and
- ///// pastes them to another Array starting at the specified destination index.
- ///// The length and the indexes are specified as 32-bit integers.
- ///// </summary>
- ///// <param name="sourceArray">The Array that contains the data to copy.</param>
- ///// <param name="sourceIndex">A 32-bit integer that represents the index in the sourceArray at which copying begins.</param>
- ///// <param name="destinationArray">The Array that receives the data.</param>
- ///// <param name="destinationIndex">A 32-bit integer that represents the index in the destinationArray at which storing begins.</param>
- ///// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
- //public static void Copy(
- // global::System.Array sourceArray,
- // int sourceIndex,
- // global::System.Array destinationArray,
- // int destinationIndex,
- // int length) {
- // var jsSource = new JsArray(sourceArray);
- // var jsDest = new JsArray(destinationArray);
- //}
+ /// <summary>
+ /// Copies a range of elements from an Array starting at the specified source index and
+ /// pastes them to another Array starting at the specified destination index.
+ /// The length and the indexes are specified as 32-bit integers.
+ /// </summary>
+ /// <param name="sourceArray">The Array that contains the data to copy.</param>
+ /// <param name="sourceIndex">A 32-bit integer that represents the index in the sourceArray at which copying begins.</param>
+ /// <param name="destinationArray">The Array that receives the data.</param>
+ /// <param name="destinationIndex">A 32-bit integer that represents the index in the destinationArray at which storing begins.</param>
+ /// <param name="length">A 32-bit integer that represents the number of elements to copy.</param>
+ public static void Copy(
+ global::System.Array sourceArray,
+ int sourceIndex,
+ global::System.Array destinationArray,
+ int destinationIndex,
+ int length) {
+
+ if (sourceArray == null)
+ throw new ArgumentNullException("sourceArray");
+
+ if (destinationArray == null)
+ throw new ArgumentNullException("destinationArray");
+
+ if (length < 0)
+ throw new ArgumentOutOfRangeException("length", "Value has to be >= 0.");
+
+ if (sourceIndex < 0)
+ throw new ArgumentOutOfRangeException("sourceIndex", "Value has to be >= 0.");
+
+ if (destinationIndex < 0)
+ throw new ArgumentOutOfRangeException("destinationIndex", "Value has to be >= 0.");
+
+ var jsSource = new JsArray(sourceArray);
+ var jsTarget = new JsArray(destinationArray);
+
+ for (int i = 0; i < length; i++) {
+ jsTarget[destinationIndex + i] = jsSource[sourceIndex + i];
+ }
+ }
#endif
}
}
Oops, something went wrong.

0 comments on commit 4797344

Please sign in to comment.