Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
2009-12-04 Sebastien Pouliot <sebastien@ximian.com>
* CodeModule.cs: Silverlight does not allow AssemblyBuilderAccess.
RunAndSave so we reduce it to AssemblyBuilderAccess.Run
[Foreport r144715]
2009-04-08 Atsushi Enomoto <atsushi@ximian.com>
* CodeWriter.cs : move into namespace.
2009-02-19 Atsushi Enomoto <atsushi@ximian.com>
* CodeTryBlock.cs : new statement support.
2009-02-19 Atsushi Enomoto <atsushi@ximian.com>
* CodeCast.cs : fix PrintCode() for no-conversion case.
2009-01-19 Atsushi Enomoto <atsushi@ximian.com>
* CodeLiteral.cs : use Convert.ChangeType() override that is
available in 2.1.
2009-01-19 Atsushi Enomoto <atsushi@ximian.com>
* CodeModule.cs : use DefineDynamicModule() which is avaiable in 2.1.
2008-07-05 Eyal Alaluf <eyala@mainsoft.com>
* CodeGenerationHelper.cs: Correctly handle enum underlying types.
2008-05-04 Eyal Alaluf <eyala@mainsoft.com>
* CodeArgumentReference.cs: Fix GetResultType () when argument type is
by-ref.
2008-04-10 Eyal Alaluf <eyala@mainsoft.com>
* CodeArgumentReference.cs, CodeGenerationHelper.cs: Added ByRef support.
2008-02-27 Eyal Alaluf <eyala@mainsoft.com>
* CodeCustomAttribute.cs CodeAssignment.cs: Fix compilation warnings.
2006-06-22 Atsushi Enomoto <atsushi@ximian.com>
* CodeArrayItem.cs, CodeAssignment.cs : some more ArgumentNull check.
2006-06-22 Atsushi Enomoto <atsushi@ximian.com>
* CodeExpression.cs : replaced all operator overloads with general
methods, especially since when operator== is overriden to have
different return type (CodeExpression) it is impossible to check
whether a variable is null or not.
* CodeForEach.cs : overriden operator < was used there.
* CodeBuilder.cs : added some null argument check.
* CodeMethodCall.cs : allow MethodBase.
2006-06-20 Atsushi Enomoto <atsushi@ximian.com>
* CodeClass.cs : removed some DefineField() overloads as they
easily brings ambiguous match at call.
2006-06-20 Atsushi Enomoto <atsushi@ximian.com>
* CodeCustomAttribute.cs : check named argument strictly (check if
the named args really exist).
2006-06-12 Atsushi Enomoto <atsushi@ximian.com>
* CodeLiteral.cs : added Value property (needed to extract value)
* CodeCustomAttribute.cs : CustomAttributeBuilder.ctor() takes
both properties and fields.
* CodeMethod.cs, CodeProperty.cs : add named-arg-less .ctor().
2006-06-12 Atsushi Enomoto <atsushi@ximian.com>
* CodeProperty.cs : setter and getter must match for each method
signature with related to the property type.
2006-06-12 Atsushi Enomoto <atsushi@ximian.com>
* CodeAdd.cs, CodeAnd.cs, CodeArgument.cs, CodeArgumentReference.cs,
CodeArithmeticOperation.cs, CodeArrayItem.cs, CodeArrayLength.cs,
CodeAssignment.cs, CodeBinaryComparison.cs, CodeBinaryOperation.cs,
CodeBlock.cs, CodeBuilder.cs, CodeCast.cs, CodeClass.cs,
CodeCustomAttribute.cs, CodeDecrement.cs, CodeEquals.cs,
CodeExpression.cs, CodeFieldReference.cs, CodeFor.cs,
CodeForeach.cs, CodeGenerationHelper.cs, CodeIf.cs,
CodeIncrement.cs, CodeIs.cs, CodeItem.cs, CodeLiteral.cs,
CodeMethod.cs, CodeMethodCall.cs, CodeModule.cs, CodeNew.cs,
CodeNewArray.cs, CodeNotEquals.cs, CodeOr.cs, CodeProperty.cs,
CodePropertyReference.cs, CodeReturn.cs, CodeSelect.cs,
CodeSelfIncrement.cs, CodeUnaryOperation.cs, CodeValueReference.cs,
CodeVariableDeclaration.cs, CodeVariableReference.cs, CodeWhen.cs,
CodeWhile.cs, CodeWriter.cs, Exp.cs :
initial import. See ../README.

View File

@@ -0,0 +1,2 @@
// created on 01/09/2004 at 02:27

View File

@@ -0,0 +1,118 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeAnd: CodeConditionExpression
{
CodeExpression exp1;
CodeExpression exp2;
Type t1;
Type t2;
public CodeAnd (CodeExpression exp1, CodeExpression exp2)
{
this.exp1 = exp1;
this.exp2 = exp2;
if (exp1.GetResultType () != typeof(bool) || exp1.GetResultType () != typeof(bool)) {
if (t1 != t2)
throw new InvalidOperationException ("Can't compare values of different primitive types");
}
}
public override void Generate (ILGenerator gen)
{
Label falseLabel = gen.DefineLabel ();
Label endLabel = gen.DefineLabel ();
if (exp1 is CodeConditionExpression)
((CodeConditionExpression)exp1).GenerateForBranch (gen, falseLabel, false);
else {
exp1.Generate (gen);
gen.Emit (OpCodes.Brfalse, falseLabel);
}
exp2.Generate (gen);
gen.Emit (OpCodes.Br, endLabel);
gen.MarkLabel(falseLabel);
gen.Emit (OpCodes.Ldc_I4_0);
gen.MarkLabel(endLabel);
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
Label endLabel = gen.DefineLabel ();
exp1.Generate (gen);
if (exp1 is CodeConditionExpression) {
if (branchCase)
((CodeConditionExpression)exp1).GenerateForBranch (gen, endLabel, false);
else
((CodeConditionExpression)exp1).GenerateForBranch (gen, label, false);
}
else {
exp1.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Brfalse, endLabel);
else
gen.Emit (OpCodes.Brfalse, label);
}
if (exp2 is CodeConditionExpression) {
if (branchCase)
((CodeConditionExpression)exp2).GenerateForBranch (gen, label, true);
else
((CodeConditionExpression)exp2).GenerateForBranch (gen, label, false);
}
else {
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Brtrue, label);
else
gen.Emit (OpCodes.Brfalse, label);
}
gen.MarkLabel(endLabel);
}
public override void PrintCode (CodeWriter cp)
{
exp1.PrintCode (cp);
cp.Write (" && ");
exp2.PrintCode (cp);
}
public override Type GetResultType ()
{
return typeof (bool);
}
}
}
#endif

View File

@@ -0,0 +1,40 @@
// created on 28/08/2004 at 17:07
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeArgument: CodeExpression
{
int argument;
public CodeArgument (int arg, Type type)
{
argument = arg;
}
public int Argument
{
get { return argument; }
}
public override void Generate (ILGenerator gen)
{
gen.Emit (OpCodes.Ldloc, var.LocalBuilder);
}
public override void PrintCode (CodeWriter cp)
{
cp.Write ("arg" + argument);
}
public override Type GetResultType ()
{
return var.Type;
}
}
}
#endif

View File

@@ -0,0 +1,83 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeArgumentReference: CodeValueReference
{
Type type;
int argNum;
string name;
public CodeArgumentReference (Type type, int argNum, string name)
{
this.type = type;
this.argNum = argNum;
this.name = name;
}
public override void Generate (ILGenerator gen)
{
switch (argNum) {
case 0: gen.Emit (OpCodes.Ldarg_0); break;
case 1: gen.Emit (OpCodes.Ldarg_1); break;
case 2: gen.Emit (OpCodes.Ldarg_2); break;
case 3: gen.Emit (OpCodes.Ldarg_3); break;
default: gen.Emit (OpCodes.Ldarg, argNum); break;
}
if (type.IsByRef)
CodeGenerationHelper.LoadFromPtr (gen, type.GetElementType ());
}
public override void GenerateSet (ILGenerator gen, CodeExpression value)
{
if (type.IsByRef) {
gen.Emit (OpCodes.Ldarg, argNum);
value.Generate (gen);
CodeGenerationHelper.GenerateSafeConversion (gen, type.GetElementType (), value.GetResultType ());
CodeGenerationHelper.SaveToPtr (gen, type.GetElementType ());
}
else {
value.Generate (gen);
CodeGenerationHelper.GenerateSafeConversion (gen, type, value.GetResultType ());
gen.Emit (OpCodes.Starg, argNum);
}
}
public override void PrintCode (CodeWriter cp)
{
cp.Write (name);
}
public override Type GetResultType ()
{
return type.IsByRef ? type.GetElementType () : type;
}
}
}
#endif

View File

@@ -0,0 +1,145 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public abstract class CodeArithmeticOperation: CodeExpression
{
protected CodeExpression exp1;
protected CodeExpression exp2;
protected Type t1;
protected Type t2;
protected string symbol;
protected CodeArithmeticOperation ()
{
}
public CodeArithmeticOperation (CodeExpression exp1, CodeExpression exp2, string symbol)
{
this.symbol = symbol;
this.exp1 = exp1;
this.exp2 = exp2;
t1 = exp1.GetResultType ();
t2 = exp2.GetResultType ();
if (!t1.IsPrimitive || !t2.IsPrimitive || (t1 != t2)) {
throw new InvalidOperationException ("Operator " + GetType().Name + " cannot be applied to operands of type '" + t1.Name + " and " + t2.Name);
}
}
public override void PrintCode (CodeWriter cp)
{
exp1.PrintCode (cp);
cp.Write (" " + symbol + " ");
exp2.PrintCode (cp);
}
public override Type GetResultType ()
{
return exp1.GetResultType();
}
}
public class CodeAdd: CodeArithmeticOperation
{
public CodeAdd (CodeExpression exp1, CodeExpression exp2)
{
this.symbol = "+";
this.exp1 = exp1;
this.exp2 = exp2;
t1 = exp1.GetResultType ();
t2 = exp2.GetResultType ();
if ((!t1.IsPrimitive || !t2.IsPrimitive || (t1 != t2)) && (t1 != typeof(string) || t2 != typeof(string))) {
throw new InvalidOperationException ("Operator " + GetType().Name + " cannot be applied to operands of type '" + t1.Name + " and " + t2.Name);
}
}
public override void Generate (ILGenerator gen)
{
if (exp1.GetResultType () == typeof(string)) {
MethodInfo m = typeof(string).GetMethod ("Concat", new Type[] { typeof(string), typeof(string) });
CodeGenerationHelper.GenerateMethodCall (gen, null, m, exp1, exp2);
}
else {
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Add);
}
}
}
public class CodeMul: CodeArithmeticOperation
{
public CodeMul (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, "*")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Mul);
}
}
public class CodeDiv: CodeArithmeticOperation
{
public CodeDiv (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, "*")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Div);
}
}
public class CodeSub: CodeArithmeticOperation
{
public CodeSub (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, "-")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Sub);
}
}
}
#endif

View File

@@ -0,0 +1,178 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeArrayItem: CodeValueReference
{
CodeExpression array;
CodeExpression index;
public CodeArrayItem (CodeExpression array, CodeExpression index)
{
if (array == null)
throw new ArgumentNullException ("array");
if (index == null)
throw new ArgumentNullException ("index");
this.array = array;
this.index = index;
}
public override void Generate (ILGenerator gen)
{
array.Generate (gen);
index.Generate (gen);
Type t = array.GetResultType().GetElementType();
if (t.IsEnum && t != typeof(Enum)) t = t.UnderlyingSystemType;
switch (Type.GetTypeCode (t))
{
case TypeCode.Byte:
gen.Emit (OpCodes.Ldelem_U1);
break;
case TypeCode.Double:
gen.Emit (OpCodes.Ldelem_R8);
break;
case TypeCode.Int16:
gen.Emit (OpCodes.Ldelem_I2);
break;
case TypeCode.UInt32:
gen.Emit (OpCodes.Ldelem_U4);
break;
case TypeCode.Int32:
gen.Emit (OpCodes.Ldelem_I4);
break;
case TypeCode.UInt64:
case TypeCode.Int64:
gen.Emit (OpCodes.Ldelem_I8);
break;
case TypeCode.SByte:
gen.Emit (OpCodes.Ldelem_I1);
break;
case TypeCode.Single:
gen.Emit (OpCodes.Ldelem_R4);
break;
case TypeCode.UInt16:
gen.Emit (OpCodes.Ldelem_U2);
break;
default:
if (t.IsValueType) {
gen.Emit (OpCodes.Ldelema, t);
CodeGenerationHelper.LoadFromPtr (gen, t);
}
else
gen.Emit (OpCodes.Ldelem_Ref);
break;
}
}
public override void GenerateSet (ILGenerator gen, CodeExpression value)
{
if (value == null)
throw new ArgumentNullException ("value");
Type t = array.GetResultType().GetElementType();
if (t.IsEnum && t != typeof(Enum)) t = t.UnderlyingSystemType;
array.Generate (gen);
index.Generate (gen);
switch (Type.GetTypeCode (t))
{
case TypeCode.Byte:
case TypeCode.SByte:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_I1);
break;
case TypeCode.Double:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_R8);
break;
case TypeCode.UInt16:
case TypeCode.Int16:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_I2);
break;
case TypeCode.UInt32:
case TypeCode.Int32:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_I4);
break;
case TypeCode.UInt64:
case TypeCode.Int64:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_I8);
break;
case TypeCode.Single:
value.Generate (gen);
gen.Emit (OpCodes.Stelem_R4);
break;
default:
if (t.IsValueType) {
gen.Emit (OpCodes.Ldelema, t);
value.Generate (gen);
gen.Emit (OpCodes.Stobj, t);
}
else {
value.Generate (gen);
gen.Emit (OpCodes.Stelem_Ref);
}
break;
}
}
public override void PrintCode (CodeWriter cp)
{
array.PrintCode (cp);
cp.Write ("[");
index.PrintCode (cp);
cp.Write ("]");
}
public override Type GetResultType ()
{
return array.GetResultType().GetElementType();
}
}
}
#endif

View File

@@ -0,0 +1,60 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeArrayLength: CodeExpression
{
CodeExpression array;
public CodeArrayLength (CodeExpression array)
{
if (!array.GetResultType().IsArray)
throw new InvalidOperationException ("CodeArrayLength can only be applied to array expressions");
this.array = array;
}
public override void Generate (ILGenerator gen)
{
array.Generate (gen);
gen.Emit (OpCodes.Ldlen);
}
public override void PrintCode (CodeWriter cp)
{
array.PrintCode (cp);
cp.Write (".Length");
}
public override Type GetResultType ()
{
return typeof(int);
}
}
}
#endif

View File

@@ -0,0 +1,74 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeAssignment: CodeExpression
{
new CodeValueReference var;
CodeExpression exp;
public CodeAssignment (CodeValueReference var, CodeExpression exp)
{
if (var == null)
throw new ArgumentNullException ("var");
if (exp == null)
throw new ArgumentNullException ("exp");
this.exp = exp;
this.var = var;
}
public override void Generate (ILGenerator gen)
{
var.GenerateSet (gen, exp);
exp.Generate (gen);
}
public override void GenerateAsStatement (ILGenerator gen)
{
CodeExpression val = exp;
if (var.GetResultType () == typeof(object) && exp.GetResultType ().IsValueType)
var.GenerateSet (gen, new CodeCast (typeof(object), exp));
else
var.GenerateSet (gen, exp);
}
public override void PrintCode (CodeWriter cp)
{
var.PrintCode (cp);
cp.Write (" = ");
exp.PrintCode (cp);
}
public override Type GetResultType ()
{
return var.GetResultType ();
}
}
}
#endif

View File

@@ -0,0 +1,170 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public abstract class CodeBinaryComparison: CodeConditionExpression
{
protected CodeExpression exp1;
protected CodeExpression exp2;
protected Type t1;
protected Type t2;
string symbol;
public CodeBinaryComparison (CodeExpression exp1, CodeExpression exp2, string symbol)
{
this.symbol = symbol;
this.exp1 = exp1;
this.exp2 = exp2;
t1 = exp1.GetResultType ();
t2 = exp2.GetResultType ();
if (!t1.IsPrimitive || !t2.IsPrimitive || (t1 != t2)) {
throw new InvalidOperationException ("Operator " + GetType().Name + " cannot be applied to operands of type '" + t1.Name + " and " + t2.Name);
}
}
public override void PrintCode (CodeWriter cp)
{
exp1.PrintCode (cp);
cp.Write (" " + symbol + " ");
exp2.PrintCode (cp);
}
public override Type GetResultType ()
{
return typeof(bool);
}
}
public class CodeGreaterThan: CodeBinaryComparison
{
public CodeGreaterThan (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, ">")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Cgt);
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
exp1.Generate (gen);
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Bgt, label);
else
gen.Emit (OpCodes.Ble, label);
}
}
public class CodeGreaterEqualThan: CodeBinaryComparison
{
public CodeGreaterEqualThan (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, ">=")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Clt);
gen.Emit (OpCodes.Ldc_I4_0);
gen.Emit (OpCodes.Ceq);
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
exp1.Generate (gen);
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Bge, label);
else
gen.Emit (OpCodes.Blt, label);
}
}
public class CodeLessThan: CodeBinaryComparison
{
public CodeLessThan (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, "<")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Clt);
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
exp1.Generate (gen);
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Blt, label);
else
gen.Emit (OpCodes.Bge, label);
}
}
public class CodeLessEqualThan: CodeBinaryComparison
{
public CodeLessEqualThan (CodeExpression exp1, CodeExpression exp2)
: base (exp1, exp2, "<=")
{
}
public override void Generate (ILGenerator gen)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Cgt);
gen.Emit (OpCodes.Ldc_I4_0);
gen.Emit (OpCodes.Ceq);
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
exp1.Generate (gen);
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Ble, label);
else
gen.Emit (OpCodes.Bgt, label);
}
}
}
#endif

View File

@@ -0,0 +1,40 @@
// created on 28/08/2004 at 17:30
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public abstract class CodeBinaryOperation: CodeConditionExpression
{
protected CodeExpression exp1;
protected CodeExpression exp2;
protected Type t1;
protected Type t2;
string symbol;
public CodeBinaryOperation (CodeExpression exp1, CodeExpression exp2, string symbol)
{
this.symbol = symbol;
this.exp1 = exp1;
this.exp2 = exp2;
t1 = exp1.GetResultType ();
t2 = exp2.GetResultType ();
if (!t1.IsPrimitive || !t2.IsPrimitive || (t1 != t2)) {
throw new InvalidOperationException ("Operator " + GetType().Name + " cannot be applied to operands of type '" + t1.Name + " and " + t2.Name);
}
}
public override void PrintCode (CodeWriter cp)
{
exp1.PrintCode (cp);
cp.Write (" " + symbol + " ");
exp2.PrintCode (cp);
}
}
}
#endif

View File

@@ -0,0 +1,90 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeBlock: CodeItem
{
ArrayList statements = new ArrayList ();
public void Add (CodeItem code)
{
statements.Add (code);
}
public bool IsEmpty
{
get { return statements.Count == 0; }
}
public static CodeBlock operator+(CodeBlock cb, CodeExpression e)
{
cb.Add (e);
return cb;
}
public CodeItem GetLastItem ()
{
return (CodeItem) statements [statements.Count - 1];
}
public override void Generate (ILGenerator gen)
{
foreach (CodeItem item in statements) {
if (item is CodeExpression)
((CodeExpression)item).GenerateAsStatement (gen);
else
item.Generate (gen);
}
}
public override void PrintCode (CodeWriter cp)
{
foreach (CodeItem item in statements) {
cp.BeginLine ();
item.PrintCode (cp);
cp.Write (";");
cp.EndLine ();
}
}
}
internal class CodePop: CodeStatement
{
public override void Generate (ILGenerator gen)
{
gen.Emit (OpCodes.Pop);
}
public override void PrintCode (CodeWriter cp)
{
}
}
}
#endif

View File

@@ -0,0 +1,425 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.IO;
using System.Collections;
using System.Reflection.Emit;
using System.Reflection;
namespace Mono.CodeGeneration
{
public class CodeBuilder
{
CodeBlock mainBlock;
CodeBlock currentBlock;
Stack blockStack = new Stack ();
int varId;
Label returnLabel;
ArrayList nestedIfs = new ArrayList();
int currentIfSerie = -1;
CodeClass codeClass;
public CodeBuilder (CodeClass codeClass)
{
this.codeClass = codeClass;
mainBlock = new CodeBlock ();
currentBlock = mainBlock;
}
CodeBuilder (CodeBlock block)
{
currentBlock = block;
}
public CodeBlock CurrentBlock
{
get {
return currentBlock;
}
}
public CodeClass OwnerClass
{
get { return codeClass; }
}
public void Generate (ILGenerator gen)
{
// try {
mainBlock.Generate (gen);
/*
}
catch (Exception ex) {
string m = ex.Message + "\nCode block:\n";
m += "-----------------------\n";
m += PrintCode ();
m += "-----------------------\n";
throw new Exception (m, ex);
}
*/
}
public string PrintCode ()
{
StringWriter sw = new StringWriter ();
CodeWriter cw = new CodeWriter (sw);
PrintCode (cw);
return sw.ToString ();
}
public void PrintCode (CodeWriter cp)
{
mainBlock.PrintCode (cp);
}
public CodeVariableReference DeclareVariable (Type type)
{
return DeclareVariable (type, null);
}
public CodeVariableReference DeclareVariable (Type type, object ob)
{
return DeclareVariable (type, Exp.Literal(ob));
}
public CodeVariableReference DeclareVariable (CodeExpression initValue)
{
return DeclareVariable (initValue.GetResultType(), initValue);
}
public CodeVariableReference DeclareVariable (Type type, CodeExpression initValue)
{
string name = "v" + (varId++);
CodeVariableDeclaration var = new CodeVariableDeclaration (type, name);
currentBlock.Add (var);
if (!object.ReferenceEquals (initValue, null))
Assign (var.Variable, initValue);
return var.Variable;
}
public void Assign (CodeValueReference var, CodeExpression val)
{
currentBlock.Add (new CodeAssignment (var, val));
}
public void If (CodeExpression condition)
{
currentBlock.Add (new CodeIf (condition));
PushNewBlock ();
nestedIfs.Add (0);
}
public void ElseIf (CodeExpression condition)
{
if (nestedIfs.Count == 0)
throw new InvalidOperationException ("'Else' not allowed here");
Else ();
currentBlock.Add (new CodeIf (condition));
PushNewBlock ();
nestedIfs [nestedIfs.Count-1] = 1 + (int)nestedIfs [nestedIfs.Count-1];
}
public void Else ()
{
CodeBlock block = PopBlock ();
CodeIf cif = currentBlock.GetLastItem () as CodeIf;
if (cif == null || cif.TrueBlock != null)
throw new InvalidOperationException ("'Else' not allowed here");
cif.TrueBlock = block;
PushNewBlock ();
}
public void EndIf ()
{
CodeBlock block = PopBlock ();
CodeIf cif = currentBlock.GetLastItem () as CodeIf;
if (cif == null || cif.FalseBlock != null || nestedIfs.Count == 0)
throw new InvalidOperationException ("'EndIf' not allowed here");
if (cif.TrueBlock == null)
cif.TrueBlock = block;
else
cif.FalseBlock = block;
int num = (int) nestedIfs [nestedIfs.Count-1];
if (num > 0) {
nestedIfs [nestedIfs.Count-1] = --num;
EndIf ();
}
else {
nestedIfs.RemoveAt (nestedIfs.Count - 1);
}
}
public void Select ()
{
currentBlock.Add (new CodeSelect ());
PushNewBlock ();
}
public void Case (CodeExpression condition)
{
PopBlock ();
CodeSelect select = currentBlock.GetLastItem () as CodeSelect;
if (select == null)
throw new InvalidOperationException ("'Case' not allowed here");
PushNewBlock ();
select.AddCase (condition, currentBlock);
}
public void EndSelect ()
{
PopBlock ();
CodeSelect select = currentBlock.GetLastItem () as CodeSelect;
if (select == null)
throw new InvalidOperationException ("'EndSelect' not allowed here");
}
public void While (CodeExpression condition)
{
currentBlock.Add (new CodeWhile (condition));
PushNewBlock ();
}
public void EndWhile ()
{
CodeBlock block = PopBlock ();
CodeWhile cif = currentBlock.GetLastItem () as CodeWhile;
if (cif == null || cif.WhileBlock != null)
throw new InvalidOperationException ("'EndWhile' not allowed here");
cif.WhileBlock = block;
}
public void Foreach (Type type, out CodeExpression item, CodeExpression array)
{
CodeForeach cfe = new CodeForeach (array, type);
item = cfe.ItemExpression;
currentBlock.Add (cfe);
PushNewBlock ();
}
public void EndForeach ()
{
CodeBlock block = PopBlock ();
CodeForeach cif = currentBlock.GetLastItem () as CodeForeach;
if (cif == null || cif.ForBlock != null)
throw new InvalidOperationException ("'EndForeach' not allowed here");
cif.ForBlock = block;
}
public void For (CodeExpression initExp, CodeExpression conditionExp, CodeExpression nextExp)
{
currentBlock.Add (new CodeFor (initExp, conditionExp, nextExp));
PushNewBlock ();
}
public void EndFor ()
{
CodeBlock block = PopBlock ();
CodeFor cif = currentBlock.GetLastItem () as CodeFor;
if (cif == null || cif.ForBlock != null)
throw new InvalidOperationException ("'EndFor' not allowed here");
cif.ForBlock = block;
}
public void Call (CodeExpression target, string name, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (name == null)
throw new ArgumentNullException ("name");
currentBlock.Add (new CodeMethodCall (target, name, parameters));
}
public void Call (CodeExpression target, MethodBase method, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (method == null)
throw new ArgumentNullException ("method");
currentBlock.Add (new CodeMethodCall (target, method, parameters));
}
public void Call (CodeExpression target, CodeMethod method, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (method == null)
throw new ArgumentNullException ("method");
currentBlock.Add (new CodeMethodCall (target, method, parameters));
}
public void Call (Type type, string name, params CodeExpression[] parameters)
{
if (type == null)
throw new ArgumentNullException ("type");
if (name == null)
throw new ArgumentNullException ("name");
currentBlock.Add (new CodeMethodCall (type, name, parameters));
}
public void Call (MethodInfo method, params CodeExpression[] parameters)
{
if (method == null)
throw new ArgumentNullException ("method");
currentBlock.Add (new CodeMethodCall (method, parameters));
}
public void Call (CodeMethod method, params CodeExpression[] parameters)
{
if ((object) method == null)
throw new ArgumentNullException ("method");
currentBlock.Add (new CodeMethodCall (method, parameters));
}
public CodeExpression CallFunc (CodeExpression target, string name, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (name == null)
throw new ArgumentNullException ("name");
return new CodeMethodCall (target, name, parameters);
}
public CodeExpression CallFunc (CodeExpression target, MethodInfo method, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (method == null)
throw new ArgumentNullException ("method");
return new CodeMethodCall (target, method, parameters);
}
public CodeExpression CallFunc (CodeExpression target, CodeMethod method, params CodeExpression[] parameters)
{
if ((object) target == null)
throw new ArgumentNullException ("target");
if (method == null)
throw new ArgumentNullException ("method");
return new CodeMethodCall (target, method, parameters);
}
public CodeExpression CallFunc (Type type, string name, params CodeExpression[] parameters)
{
if (type == null)
throw new ArgumentNullException ("type");
if (name == null)
throw new ArgumentNullException ("name");
return new CodeMethodCall (type, name, parameters);
}
public CodeExpression CallFunc (MethodInfo method, params CodeExpression[] parameters)
{
if (method == null)
throw new ArgumentNullException ("method");
return new CodeMethodCall (method, parameters);
}
public CodeExpression CallFunc (CodeMethod method, params CodeExpression[] parameters)
{
if ((object) method == null)
throw new ArgumentNullException ("method");
return new CodeMethodCall (method, parameters);
}
public void Inc (CodeValueReference val)
{
Assign (val, new CodeIncrement (val));
}
public void Dec (CodeValueReference val)
{
Assign (val, new CodeDecrement (val));
}
public CodeExpression When (CodeExpression condition, CodeExpression trueResult, CodeExpression falseResult)
{
return new CodeWhen (condition, trueResult, falseResult);
}
public void ConsoleWriteLine (params CodeExpression[] parameters)
{
Call (typeof(Console), "WriteLine", parameters);
}
public void ConsoleWriteLine (params object[] parameters)
{
CodeExpression[] exps = new CodeExpression [parameters.Length];
for (int n=0; n<exps.Length; n++)
exps[n] = Exp.Literal (parameters[n]);
ConsoleWriteLine (exps);
}
public void Return (CodeExpression exp)
{
currentBlock.Add (new CodeReturn (this, exp));
}
public void Return ()
{
currentBlock.Add (new CodeReturn (this));
}
public static CodeBuilder operator+(CodeBuilder cb, CodeItem e)
{
cb.currentBlock.Add (e);
return cb;
}
internal Label ReturnLabel
{
get { return returnLabel; }
set { returnLabel = value; }
}
void PushNewBlock ()
{
blockStack.Push (currentBlock);
currentBlock = new CodeBlock ();
}
CodeBlock PopBlock ()
{
CodeBlock block = currentBlock;
currentBlock = (CodeBlock) blockStack.Pop ();
return block;
}
}
}
#endif

View File

@@ -0,0 +1,135 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
using Mono.CodeGeneration;
namespace Mono.CodeGeneration
{
public class CodeCast: CodeExpression
{
Type type;
CodeExpression exp;
public CodeCast (Type type, CodeExpression exp)
{
this.type = type;
this.exp = exp;
}
public override void Generate (ILGenerator gen)
{
exp.Generate (gen);
Type typeObj = exp.GetResultType ();
if (type.IsAssignableFrom (typeObj)) {
if (typeObj.IsValueType)
gen.Emit (OpCodes.Box, typeObj);
return;
}
else if (type.IsValueType && typeObj == typeof(object)) {
// Unbox
gen.Emit (OpCodes.Unbox, type);
CodeGenerationHelper.LoadFromPtr (gen, type);
return;
}
else if (typeObj.IsAssignableFrom (type)) {
// Sub s = (Sub)base
gen.Emit (OpCodes.Castclass, type);
return;
}
else if (CodeGenerationHelper.IsNumber (type) && CodeGenerationHelper.IsNumber (typeObj)) {
switch (Type.GetTypeCode (type))
{
case TypeCode.Byte:
gen.Emit (OpCodes.Conv_U1);
return;
case TypeCode.Double:
gen.Emit (OpCodes.Conv_R8);
return;
case TypeCode.Int16:
gen.Emit (OpCodes.Conv_I2);
return;
case TypeCode.Int32:
gen.Emit (OpCodes.Conv_I4);
return;
case TypeCode.Int64:
gen.Emit (OpCodes.Conv_I8);
return;
case TypeCode.SByte:
gen.Emit (OpCodes.Conv_I1);
return;
case TypeCode.Single:
gen.Emit (OpCodes.Conv_R4);
return;
case TypeCode.UInt16:
gen.Emit (OpCodes.Conv_U2);
return;
case TypeCode.UInt32:
gen.Emit (OpCodes.Conv_U4);
return;
case TypeCode.UInt64:
gen.Emit (OpCodes.Conv_U8);
return;
}
}
MethodInfo imp = type.GetMethod ("op_Implicit", new Type[] { typeObj });
if (imp != null) {
gen.Emit (OpCodes.Call, imp);
return;
}
foreach (MethodInfo m in typeObj.GetMember ("op_Explicit"))
if (m.ReturnType == type) {
gen.Emit (OpCodes.Call, m);
return;
}
throw new InvalidOperationException ("Can't cast from " + typeObj + " to " + type);
}
public override void PrintCode (CodeWriter cp)
{
Type typeObj = exp.GetResultType ();
if (type.IsAssignableFrom (typeObj)) {
exp.PrintCode (cp);
return;
}
cp.Write ("((" + type.FullName + ") ");
exp.PrintCode (cp);
cp.Write (")");
}
public override Type GetResultType ()
{
return type;
}
}
}
#endif

View File

@@ -0,0 +1,350 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeClass
{
TypeBuilder typeBuilder;
ArrayList customAttributes = new ArrayList ();
ArrayList methods = new ArrayList ();
ArrayList properties = new ArrayList ();
ArrayList fields = new ArrayList ();
Hashtable fieldAttributes = new Hashtable ();
Type baseType;
Type[] interfaces;
CodeMethod ctor;
CodeMethod cctor;
CodeBuilder instanceInit;
CodeBuilder classInit;
int varId;
public CodeClass (ModuleBuilder mb, string name)
: this (mb, name, TypeAttributes.Public, typeof(object))
{
}
public CodeClass (ModuleBuilder mb, string name, Type baseType, params Type[] interfaces)
: this (mb, name, TypeAttributes.Public, baseType, interfaces)
{
}
public CodeClass (ModuleBuilder mb, string name, TypeAttributes attr, Type baseType, params Type[] interfaces)
{
typeBuilder = mb.DefineType (name, attr, baseType, interfaces);
this.baseType = baseType;
this.interfaces = interfaces;
}
public CodeCustomAttribute CreateCustomAttribute (Type attributeType)
{
return CreateCustomAttribute (attributeType,
Type.EmptyTypes, new object [0], new string [0], new object [0]);
}
public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs, string [] namedArgFieldNames, object [] namedArgValues)
{
CodeCustomAttribute cca = CodeCustomAttribute.Create (
attributeType, ctorArgTypes, ctorArgs, namedArgFieldNames, namedArgValues);
typeBuilder.SetCustomAttribute (cca.Builder);
customAttributes.Add (cca);
return cca;
}
public CodeCustomAttribute CreateCustomAttribute (Type attributeType, Type [] ctorArgTypes, CodeLiteral [] ctorArgs, FieldInfo [] fields, CodeLiteral [] fieldValues)
{
CodeCustomAttribute cca = CodeCustomAttribute.Create (
attributeType, ctorArgTypes, ctorArgs, fields, fieldValues);
typeBuilder.SetCustomAttribute (cca.Builder);
customAttributes.Add (cca);
return cca;
}
public CodeProperty CreateProperty (string name, Type returnType, params Type [] parameterTypes)
{
return CreateProperty (name, returnType, MethodAttributes.Private, parameterTypes);
}
public CodeProperty CreateProperty (string name, Type returnType, MethodAttributes methodAttributes, params Type [] parameterTypes)
{
CodeProperty prop = new CodeProperty (this, GetPropertyName (name), PropertyAttributes.None, methodAttributes, returnType, parameterTypes);
properties.Add (prop);
return prop;
}
public CodeMethod CreateMethod (string name, Type returnType, params Type[] parameterTypes)
{
CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public, returnType, parameterTypes);
methods.Add (met);
return met;
}
public CodeMethod CreateVirtualMethod (string name, Type returnType, params Type[] parameterTypes)
{
CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterTypes);
methods.Add (met);
return met;
}
public CodeMethod CreateStaticMethod (string name, Type returnType, params Type[] parameterTypes)
{
CodeMethod met = new CodeMethod (this, GetMethodName (name), MethodAttributes.Public | MethodAttributes.Static, returnType, parameterTypes);
methods.Add (met);
return met;
}
public CodeMethod CreateMethod (string name, MethodAttributes attributes, Type returnType, params Type[] parameterTypes)
{
CodeMethod met = new CodeMethod (this, GetMethodName (name), attributes, returnType, parameterTypes);
methods.Add (met);
return met;
}
public CodeMethod GetDefaultConstructor ()
{
if (ctor != null) return ctor;
ctor = CreateConstructor (MethodAttributes.Public, Type.EmptyTypes);
return ctor;
}
public CodeMethod CreateConstructor (params Type[] parameters)
{
return CreateConstructor (MethodAttributes.Private, parameters);
}
public CodeMethod CreateConstructor (MethodAttributes attributes, params Type[] parameters)
{
if (ctor != null) return ctor;
ctor = CodeMethod.DefineConstructor (this, attributes, parameters);
methods.Add (ctor);
CodeBuilder cb = GetInstanceInitBuilder ();
ctor.CodeBuilder.CurrentBlock.Add (cb.CurrentBlock);
return ctor;
}
public CodeMethod GetStaticConstructor ()
{
if (cctor != null) return cctor;
cctor = CodeMethod.DefineConstructor (this, MethodAttributes.Public | MethodAttributes.Static, Type.EmptyTypes);
methods.Add (cctor);
CodeBuilder cb = GetClassInitBuilder ();
cctor.CodeBuilder.CurrentBlock.Add (cb.CurrentBlock);
return cctor;
}
public CodeMethod ImplementMethod (Type baseType, string methodName)
{
MethodInfo basem = baseType.GetMethod (methodName);
return ImplementMethod (baseType, basem);
}
public CodeMethod ImplementMethod (MethodInfo basem)
{
return ImplementMethod (basem.DeclaringType, basem);
}
public CodeMethod ImplementMethod (Type baseType, MethodInfo basem)
{
ParameterInfo[] pinfos = basem.GetParameters ();
Type[] pars = new Type[pinfos.Length];
for (int n=0; n<pinfos.Length; n++)
pars[n] = pinfos[n].ParameterType;
CodeMethod met = CodeMethod.DefineMethod (this, basem.Name, MethodAttributes.Public | MethodAttributes.Virtual, basem.ReturnType, pars);
typeBuilder.DefineMethodOverride (met.MethodInfo, basem);
methods.Add (met);
return met;
}
public CodeFieldReference DefineField (string name, Type type, params CodeCustomAttribute [] customAttributes)
{
return DefineField (GetFieldName (name), type, FieldAttributes.Public, null, customAttributes);
}
public CodeFieldReference DefineStaticField (CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
{
return DefineField (GetFieldName (null), initialValue.GetResultType(), FieldAttributes.Public | FieldAttributes.Static, initialValue, customAttributes);
}
public CodeFieldReference DefineStaticField (string name, Type type, CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
{
return DefineField (GetFieldName (name), type, FieldAttributes.Public | FieldAttributes.Static, initialValue, customAttributes);
}
public CodeFieldReference DefineField (string name, Type type, FieldAttributes attrs, CodeExpression initialValue, params CodeCustomAttribute [] customAttributes)
{
FieldBuilder fb = typeBuilder.DefineField (GetFieldName (name), type, attrs);
foreach (CodeCustomAttribute a in customAttributes)
fb.SetCustomAttribute (a.Builder);
fieldAttributes [fb] = new ArrayList (customAttributes);
fields.Add (fb);
CodeFieldReference fr;
if ((attrs & FieldAttributes.Static) != 0)
fr = new CodeFieldReference (fb);
else
fr = new CodeFieldReference (new CodeArgumentReference (TypeBuilder, 0, "this"), fb);
if (null != (object) initialValue) {
CodeBuilder cb = (attrs & FieldAttributes.Static) == 0 ? GetInstanceInitBuilder () : GetClassInitBuilder ();
cb.Assign (fr, initialValue);
}
return fr;
}
public TypeBuilder TypeBuilder
{
get { return typeBuilder; }
}
private CodeBuilder GetInstanceInitBuilder ()
{
if (instanceInit != null) return instanceInit;
instanceInit = new CodeBuilder (this);
return instanceInit;
}
private CodeBuilder GetClassInitBuilder ()
{
if (classInit != null) return classInit;
classInit = new CodeBuilder (this);
return classInit;
}
private string GetFieldName (string name)
{
if (name == null) return "__field_" + (varId++);
else return name;
}
private string GetMethodName (string name)
{
if (name == null) return "__Method_" + (varId++);
else return name;
}
private string GetPropertyName (string name)
{
if (name == null) return "__Property_" + (varId++);
else return name;
}
public string PrintCode ()
{
StringWriter sw = new StringWriter ();
CodeWriter cw = new CodeWriter (sw);
PrintCode (cw);
return sw.ToString ();
}
public void PrintCode (CodeWriter cw)
{
for (int n=0; n<customAttributes.Count; n++) {
CodeCustomAttribute cca = customAttributes [n] as CodeCustomAttribute;
if (n > 0) cw.WriteLine ("");
cca.PrintCode (cw);
}
/* if ((typeBuilder.Attributes & TypeAttributes.Abstract) != 0) cw.Write ("abstract ");
if ((typeBuilder.Attributes & TypeAttributes.NestedAssembly) != 0) cw.Write ("internal ");
if ((typeBuilder.Attributes & TypeAttributes.NestedPrivate) != 0) cw.Write ("private ");
*/ if ((typeBuilder.Attributes & TypeAttributes.Public) != 0) cw.Write ("public ");
cw.Write ("class ").Write (typeBuilder.Name);
bool dots = false;
if (baseType != null && baseType != typeof(object)) {
cw.Write (" : " + baseType);
dots = true;
}
if (interfaces != null && interfaces.Length > 0) {
if (!dots) cw.Write (" : ");
else cw.Write (", ");
for (int n=0; n<interfaces.Length; n++) {
if (n > 0) cw.Write (", ");
cw.Write (interfaces[n].ToString ());
}
}
cw.EndLine ().WriteLineInd ("{");
foreach (FieldInfo f in fields) {
cw.BeginLine ();
ArrayList atts = (ArrayList) fieldAttributes [f];
foreach (CodeCustomAttribute a in atts)
a.PrintCode (cw);
if ((f.Attributes & FieldAttributes.Static) != 0)
cw.Write ("static ");
cw.Write (f.FieldType.Name + " ");
cw.Write (f.Name + ";");
cw.EndLine ();
cw.WriteLine ("");
}
for (int n=0; n<properties.Count; n++) {
CodeProperty prop = properties [n] as CodeProperty;
if (n > 0) cw.WriteLine ("");
prop.PrintCode (cw);
}
for (int n=0; n<methods.Count; n++) {
CodeMethod met = methods[n] as CodeMethod;
if (n > 0) cw.WriteLine ("");
met.PrintCode (cw);
}
cw.WriteLineUnind ("}");
}
public Type CreateType ()
{
if (ctor == null)
ctor = GetDefaultConstructor ();
foreach (CodeProperty prop in properties)
prop.Generate ();
foreach (CodeMethod met in methods)
met.Generate ();
Type t = typeBuilder.CreateType ();
foreach (CodeMethod met in methods)
met.UpdateMethodBase (t);
foreach (CodeProperty prop in properties)
prop.UpdatePropertyInfo (t);
return t;
}
}
}
#endif

View File

@@ -0,0 +1,149 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#if !FULL_AOT_RUNTIME
using System;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeCustomAttribute
{
public static CodeCustomAttribute Create (Type attributeType)
{
return Create (attributeType, Type.EmptyTypes, new object [0], new string [0], new object [0]);
}
public static CodeCustomAttribute Create (Type attributeType, Type [] ctorArgTypes, object [] ctorArgs, string [] namedArgNames, object [] namedArgValues)
{
MemberInfo [] members = new MemberInfo [namedArgNames.Length];
for (int i = 0; i < namedArgNames.Length; i++) {
members [i] = attributeType.GetField (namedArgNames [i]);
if (members [i] == null)
members [i] = attributeType.GetProperty (namedArgNames [i]);
if (members [i] == null)
throw new ArgumentException (String.Format ("Named argument {0} was not found in attribute type {1}", namedArgNames [i], attributeType));
}
CodeLiteral [] args = new CodeLiteral [ctorArgs.Length];
for (int i = 0; i < args.Length; i++)
args [i] = new CodeLiteral (ctorArgs [i]);
CodeLiteral [] nargs = new CodeLiteral [namedArgValues.Length];
for (int i = 0; i < nargs.Length; i++)
nargs [i] = new CodeLiteral (namedArgValues [i]);
return Create (attributeType, ctorArgTypes, args, members, nargs);
}
public static CodeCustomAttribute Create (Type attributeType, Type [] ctorArgTypes, CodeLiteral [] ctorArgs, MemberInfo [] members, CodeLiteral [] values)
{
ArrayList props = new ArrayList ();
ArrayList pvalues = new ArrayList ();
ArrayList fields = new ArrayList ();
ArrayList fvalues = new ArrayList ();
for (int i = 0; i < members.Length; i++) {
if (members [i] == null)
throw new ArgumentException (String.Format ("MemberInfo at {0} was null for type {1}.", i, attributeType));
if (members [i] is PropertyInfo) {
props.Add ((PropertyInfo) members [i]);
pvalues.Add (values [i].Value);
} else {
fields.Add ((FieldInfo) members [i]);
fvalues.Add (values [i].Value);
}
}
ConstructorInfo ci = attributeType.GetConstructor (ctorArgTypes);
CustomAttributeBuilder cab = new CustomAttributeBuilder (
ci, ctorArgs,
(PropertyInfo []) props.ToArray (typeof (PropertyInfo)), pvalues.ToArray (),
(FieldInfo []) fields.ToArray (typeof (FieldInfo)), fvalues.ToArray ());
CodeCustomAttribute attr = new CodeCustomAttribute (
cab, attributeType, ci, ctorArgs, members, values);
return attr;
}
CustomAttributeBuilder customAttributeBuilder;
Type type;
ConstructorInfo constructor;
CodeLiteral [] ctorArgs;
MemberInfo [] members;
CodeLiteral [] namedArgValues;
public CodeCustomAttribute (
CustomAttributeBuilder attributeBuilder,
Type type,
ConstructorInfo constructor,
CodeLiteral [] ctorArgs,
MemberInfo [] namedArgMembers,
CodeLiteral [] namedArgValues)
{
this.type = type;
this.constructor = constructor;
this.customAttributeBuilder = attributeBuilder;
this.ctorArgs = ctorArgs;
this.members = namedArgMembers;
this.namedArgValues = namedArgValues;
}
public CustomAttributeBuilder Builder {
get { return customAttributeBuilder; }
}
public string PrintCode ()
{
StringWriter sw = new StringWriter ();
CodeWriter cw = new CodeWriter (sw);
PrintCode (cw);
return sw.ToString ();
}
public void PrintCode (CodeWriter cw)
{
cw.Write ("[").Write (type.Name).Write ("(");
if (ctorArgs.Length > 0) {
for (int i = 0; i < ctorArgs.Length - 1; i++) {
ctorArgs [i].PrintCode (cw);
cw.Write (", ");
}
ctorArgs [ctorArgs.Length - 1].PrintCode (cw);
}
if (members.Length > 0) {
if (ctorArgs.Length > 0)
cw.Write (", ");
for (int i = 0; i < members.Length; i++) {
cw.Write (members [i].Name).Write (" = ");
namedArgValues [i].PrintCode (cw);
if (i < members.Length - 1)
cw.Write (", ");
}
}
cw.Write (" )]");
cw.EndLine ();
}
}
}
#endif

View File

@@ -0,0 +1,150 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeDecrement: CodeValueReference
{
CodeValueReference exp;
public CodeDecrement (CodeValueReference exp)
{
this.exp = exp;
}
public override void Generate (ILGenerator gen)
{
exp.GenerateSet (gen, new CodeSubstractOne (exp));
exp.Generate (gen);
}
public override void GenerateSet (ILGenerator gen, CodeExpression value)
{
exp.GenerateSet (gen, value);
}
public override void PrintCode (CodeWriter cp)
{
exp.PrintCode (cp);
cp.Write ("--");
}
public override Type GetResultType ()
{
return exp.GetResultType();
}
}
public class CodeSubstractOne: CodeExpression
{
CodeExpression exp;
MethodInfo decMet;
public CodeSubstractOne (CodeExpression exp)
{
this.exp = exp;
if (!exp.IsNumber) {
decMet = exp.GetResultType ().GetMethod ("op_Decrement");
if (decMet == null)
throw new InvalidOperationException ("Operator '--' cannot be applied to operand of type '" + exp.GetResultType().FullName + "'");
}
}
public override void Generate (ILGenerator gen)
{
if (decMet != null) {
CodeGenerationHelper.GenerateMethodCall (gen, null, decMet, exp);
return;
}
exp.Generate (gen);
Type t = exp.GetResultType ();
switch (Type.GetTypeCode (t))
{
case TypeCode.Byte:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Sub);
gen.Emit (OpCodes.Conv_U1);
break;
case TypeCode.Double:
gen.Emit (OpCodes.Ldc_R8, 1);
gen.Emit (OpCodes.Sub);
break;
case TypeCode.Int16:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Sub);
gen.Emit (OpCodes.Conv_I2);
break;
case TypeCode.UInt32:
case TypeCode.Int32:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Sub);
break;
case TypeCode.UInt64:
case TypeCode.Int64:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Conv_U8);
gen.Emit (OpCodes.Sub);
break;
case TypeCode.SByte:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Sub);
gen.Emit (OpCodes.Conv_I1);
break;
case TypeCode.Single:
gen.Emit (OpCodes.Ldc_R4, 1);
gen.Emit (OpCodes.Sub);
break;
case TypeCode.UInt16:
gen.Emit (OpCodes.Ldc_I4_1);
gen.Emit (OpCodes.Sub);
gen.Emit (OpCodes.Conv_U2);
break;
}
}
public override void PrintCode (CodeWriter cp)
{
exp.PrintCode (cp);
cp.Write ("--");
}
public override Type GetResultType ()
{
return exp.GetResultType();
}
}
}
#endif

View File

@@ -0,0 +1,102 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeEquals: CodeConditionExpression
{
CodeExpression exp1;
CodeExpression exp2;
Type t1;
Type t2;
public CodeEquals (CodeExpression exp1, CodeExpression exp2)
{
this.exp1 = exp1;
this.exp2 = exp2;
t1 = exp1.GetResultType ();
t2 = exp2.GetResultType ();
if (t1.IsValueType && t2.IsValueType) {
if (t1 != t2)
throw new InvalidOperationException ("Can't compare values of different primitive types");
}
}
public override void Generate (ILGenerator gen)
{
if (t1.IsPrimitive)
{
exp1.Generate (gen);
exp2.Generate (gen);
gen.Emit (OpCodes.Ceq);
}
else
{
exp1.Generate (gen);
exp2.Generate (gen);
// gen.Emit (OpCodes.Ceq);
gen.EmitCall (OpCodes.Callvirt, t1.GetMethod ("Equals", new Type[] {t2}), null);
}
}
public override void GenerateForBranch (ILGenerator gen, Label label, bool branchCase)
{
if (t1.IsPrimitive)
{
exp1.Generate (gen);
exp2.Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Beq, label);
else
gen.Emit (OpCodes.Bne_Un, label);
}
else {
Generate (gen);
if (branchCase)
gen.Emit (OpCodes.Brtrue, label);
else
gen.Emit (OpCodes.Brfalse, label);
}
}
public override void PrintCode (CodeWriter cp)
{
exp1.PrintCode (cp);
cp.Write (" == ");
exp2.PrintCode (cp);
}
public override Type GetResultType ()
{
return typeof (bool);
}
}
}
#endif

View File

@@ -0,0 +1,200 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public abstract class CodeExpression: CodeItem
{
internal CodeVariableReference var;
public abstract Type GetResultType ();
public virtual void GenerateAsStatement (ILGenerator gen)
{
Generate (gen);
gen.Emit (OpCodes.Pop);
}
public CodeExpression CallToString ()
{
return new CodeMethodCall (this, "ToString");
}
public static CodeExpression AreEqual (CodeExpression e1, CodeExpression e2)
{
return new CodeEquals (e1, e2);
}
public static CodeExpression AreNotEqual (CodeExpression e1, CodeExpression e2)
{
return new CodeNotEquals (e1, e2);
}
public static CodeExpression IsGreaterThan (CodeExpression e1, CodeExpression e2)
{
return new CodeGreaterThan (e1, e2);
}
public static CodeExpression IsSmallerThan (CodeExpression e1, CodeExpression e2)
{
return new CodeLessThan (e1, e2);
}
public static CodeExpression IsGreaterEqualThan (CodeExpression e1, CodeExpression e2)
{
return new CodeGreaterEqualThan (e1, e2);
}
public static CodeExpression IsSmallerEqualThan (CodeExpression e1, CodeExpression e2)
{
return new CodeLessEqualThan (e1, e2);
}
public static CodeExpression Not (CodeExpression e)
{
return new CodeNot (e);
}
public static CodeExpression Add (CodeExpression e1, CodeExpression e2)
{
return new CodeAdd (e1, e2);
}
public static CodeExpression Subtract (CodeExpression e1, CodeExpression e2)
{
return new CodeSub (e1, e2);
}
public static CodeExpression Multiply (CodeExpression e1, CodeExpression e2)
{
return new CodeMul (e1, e2);
}
public static CodeExpression Divide (CodeExpression e1, CodeExpression e2)
{
return new CodeDiv (e1, e2);
}
public CodeExpression CastTo (Type type)
{
return new CodeCast (type, this);
}
public CodeExpression And (CodeExpression other)
{
return new CodeAnd (this, other);
}
public CodeExpression Is (Type type)
{
return new CodeIs (type, this);
}
public CodeExpression Call (string name, params CodeExpression[] parameters)
{
return new CodeMethodCall (this, name, parameters);
}
public CodeExpression Call (MethodInfo method, params CodeExpression[] parameters)
{
return new CodeMethodCall (this, method, parameters);
}
public CodeValueReference MemGet (string name)
{
MemberInfo[] mems = GetResultType().GetMember (name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
if (mems.Length == 0) throw new InvalidOperationException ("Field '" + name + "' not found in " + GetResultType());
return MemGet (mems[0]);
}
public CodeValueReference MemGet (MemberInfo member)
{
if (member is FieldInfo)
return new CodeFieldReference (this, (FieldInfo)member);
else if (member is PropertyInfo)
return new CodePropertyReference (this, (PropertyInfo)member);
else
throw new InvalidOperationException (member.Name + " is not either a field or a property");
}
public CodeValueReference this [CodeExpression index]
{
get { return new CodeArrayItem (this, index); }
}
public CodeValueReference this [string name]
{
get { return MemGet (name); }
}
public CodeValueReference this [FieldInfo field]
{
get { return new CodeFieldReference (this, field); }
}
public CodeValueReference this [PropertyInfo prop]
{
get { return new CodePropertyReference (this, prop); }
}
public CodeExpression ArrayLength
{
get { return new CodeArrayLength (this); }
}
public CodeExpression IsNull
{
get { return new CodeEquals (this, new CodeLiteral (null, this.GetResultType())); }
}
public static CodeExpression NullValue (Type type)
{
return new CodeLiteral (null, type);
}
public bool IsNumber
{
get {
return CodeGenerationHelper.IsNumber (GetResultType ());
}
}
}
public abstract class CodeConditionExpression: CodeExpression
{
public virtual void GenerateForBranch (ILGenerator gen, Label label, bool jumpCase)
{
Generate (gen);
if (jumpCase)
gen.Emit (OpCodes.Brtrue, label);
else
gen.Emit (OpCodes.Brfalse, label);
}
}
}
#endif

View File

@@ -0,0 +1,94 @@
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (C) Lluis Sanchez Gual, 2004
//
#if !FULL_AOT_RUNTIME
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace Mono.CodeGeneration
{
public class CodeFieldReference: CodeValueReference
{
CodeExpression target;
FieldInfo field;
public CodeFieldReference (CodeExpression target, FieldInfo field)
{
if (field.IsStatic)
throw new InvalidOperationException ("Static member '" + field.Name + "' cannot be accessed with an instance reference.");
this.target = target;
this.field = field;
}
public CodeFieldReference (FieldInfo field)
{
if (!field.IsStatic)
throw new InvalidOperationException ("An object reference is required for the non-static field '" + field.Name + "'.");
this.field = field;
}
public override void Generate (ILGenerator gen)
{
if (field.IsStatic) {
gen.Emit (OpCodes.Ldsfld, field);
}
else {
target.Generate (gen);
gen.Emit (OpCodes.Ldfld, field);
}
}
public override void GenerateSet (ILGenerator gen, CodeExpression value)
{
if (field.IsStatic) {
value.Generate (gen);
CodeGenerationHelper.GenerateSafeConversion (gen, field.FieldType, value.GetResultType ());
gen.Emit (OpCodes.Stsfld, field);
}
else {
target.Generate (gen);
value.Generate (gen);
CodeGenerationHelper.GenerateSafeConversion (gen, field.FieldType, value.GetResultType ());
gen.Emit (OpCodes.Stfld, field);
}
}
public override void PrintCode (CodeWriter cp)
{
if (!field.IsStatic)
target.PrintCode (cp);
else
cp.Write (field.DeclaringType.Name);
cp.Write (".");
cp.Write (field.Name);
}
public override Type GetResultType ()
{
return field.FieldType;
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More