/// <summary> /// Generates CIL for the expression. /// </summary> /// <param name="generator"> The generator to output the CIL to. </param> /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param> public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo) { // Generate a new method. this.context.GenerateCode(); // Add the generated method to the nested function list. if (optimizationInfo.NestedFunctions == null) optimizationInfo.NestedFunctions = new List<GeneratedMethod>(); optimizationInfo.NestedFunctions.Add(this.context.GeneratedMethod); // Add all the nested methods to the parent list. if (this.context.GeneratedMethod.Dependencies != null) { foreach (var nestedFunctionExpression in this.context.GeneratedMethod.Dependencies) optimizationInfo.NestedFunctions.Add(nestedFunctionExpression); } // Store the generated method in the cache. long generatedMethodID = GeneratedMethod.Save(this.context.GeneratedMethod); // Create a UserDefinedFunction. // prototype EmitHelpers.LoadScriptEngine(generator); generator.Call(ReflectionHelpers.ScriptEngine_Function); generator.Call(ReflectionHelpers.FunctionInstance_InstancePrototype); // name generator.LoadString(this.FunctionName); // argumentNames generator.LoadInt32(this.ArgumentNames.Count); generator.NewArray(typeof(string)); for (int i = 0; i < this.ArgumentNames.Count; i++) { generator.Duplicate(); generator.LoadInt32(i); generator.LoadString(this.ArgumentNames[i]); generator.StoreArrayElement(typeof(string)); } // scope EmitHelpers.LoadScope(generator); // bodyText generator.LoadString(this.BodyText); // body generator.LoadInt64(generatedMethodID); generator.Call(ReflectionHelpers.GeneratedMethod_Load); // strictMode generator.LoadBoolean(this.context.StrictMode); // new UserDefinedFunction(ObjectInstance prototype, string name, IList<string> argumentNames, DeclarativeScope scope, Func<Scope, object, object[], object> body, bool strictMode) generator.NewObject(ReflectionHelpers.UserDefinedFunction_Constructor); }
/// <summary> /// Emits the given value. Only possible for certain types. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="value"> The value to emit. </param> public static void EmitValue(ILGenerator generator, object value) { if (value == null) { generator.LoadNull(); } else { switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Boolean: generator.LoadBoolean((bool)value); break; case TypeCode.Byte: generator.LoadInt32((byte)value); break; case TypeCode.Char: generator.LoadInt32((char)value); break; case TypeCode.Double: generator.LoadDouble((double)value); break; case TypeCode.Int16: generator.LoadInt32((short)value); break; case TypeCode.Int32: generator.LoadInt32((int)value); break; case TypeCode.Int64: generator.LoadInt64((long)value); break; case TypeCode.SByte: generator.LoadInt32((sbyte)value); break; case TypeCode.Single: generator.LoadDouble((float)value); break; case TypeCode.String: generator.LoadString((string)value); break; case TypeCode.UInt16: generator.LoadInt32((ushort)value); break; case TypeCode.UInt32: generator.LoadInt32((uint)value); break; case TypeCode.UInt64: generator.LoadInt64((ulong)value); break; case TypeCode.Object: case TypeCode.Empty: case TypeCode.DateTime: case TypeCode.DBNull: case TypeCode.Decimal: throw new NotImplementedException(string.Format("Cannot emit the value '{0}'", value)); } } }
/// <summary> /// Emits the given value. Only possible for certain types. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="value"> The value to emit. </param> public static void EmitValue(ILGenerator generator, object value) { if (value == null) generator.LoadNull(); else { switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Boolean: generator.LoadBoolean((bool)value); break; case TypeCode.Byte: generator.LoadInt32((byte)value); break; case TypeCode.Char: generator.LoadInt32((char)value); break; case TypeCode.Double: generator.LoadDouble((double)value); break; case TypeCode.Int16: generator.LoadInt32((short)value); break; case TypeCode.Int32: generator.LoadInt32((int)value); break; case TypeCode.Int64: generator.LoadInt64((long)value); break; case TypeCode.SByte: generator.LoadInt32((sbyte)value); break; case TypeCode.Single: generator.LoadDouble((float)value); break; case TypeCode.String: generator.LoadString((string)value); break; case TypeCode.UInt16: generator.LoadInt32((ushort)value); break; case TypeCode.UInt32: generator.LoadInt32((uint)value); break; case TypeCode.UInt64: generator.LoadInt64((ulong)value); break; case TypeCode.Object: case TypeCode.Empty: case TypeCode.DateTime: case TypeCode.DBNull: case TypeCode.Decimal: throw new NotImplementedException(string.Format("Cannot emit the value '{0}'", value)); } } }
/// <summary> /// Generates CIL for the expression. /// </summary> /// <param name="generator"> The generator to output the CIL to. </param> /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param> public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo) { // Generate a new method. this.context.GenerateCode(); // Add the generated method to the nested function list. if (optimizationInfo.NestedFunctions == null) { optimizationInfo.NestedFunctions = new List <GeneratedMethod>(); } optimizationInfo.NestedFunctions.Add(this.context.GeneratedMethod); // Add all the nested methods to the parent list. if (this.context.GeneratedMethod.Dependencies != null) { foreach (var nestedFunctionExpression in this.context.GeneratedMethod.Dependencies) { optimizationInfo.NestedFunctions.Add(nestedFunctionExpression); } } // Store the generated method in the cache. long generatedMethodID = GeneratedMethod.Save(this.context.GeneratedMethod); // Create a UserDefinedFunction. // prototype EmitHelpers.LoadScriptEngine(generator); generator.Call(ReflectionHelpers.ScriptEngine_Function); generator.Call(ReflectionHelpers.FunctionInstance_InstancePrototype); // name if (this.context.DeclarationType == FunctionDeclarationType.Getter) { generator.LoadString("get " + this.FunctionName); } else if (this.context.DeclarationType == FunctionDeclarationType.Setter) { generator.LoadString("set " + this.FunctionName); } else { generator.LoadString(this.FunctionName); } // argumentNames generator.LoadInt32(this.Arguments.Count); generator.NewArray(typeof(string)); for (int i = 0; i < this.Arguments.Count; i++) { generator.Duplicate(); generator.LoadInt32(i); generator.LoadString(this.Arguments[i].Name); generator.StoreArrayElement(typeof(string)); } // scope EmitHelpers.LoadScope(generator); // bodyText generator.LoadString(this.BodyText); // body generator.LoadInt64(generatedMethodID); generator.Call(ReflectionHelpers.GeneratedMethod_Load); // strictMode generator.LoadBoolean(this.context.StrictMode); // new UserDefinedFunction(ObjectInstance prototype, string name, IList<string> argumentNames, DeclarativeScope scope, Func<Scope, object, object[], object> body, bool strictMode) generator.NewObject(ReflectionHelpers.UserDefinedFunction_Constructor); }
/// <summary> /// Generates CIL for the expression. /// </summary> /// <param name="generator"> The generator to output the CIL to. </param> /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param> public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo) { // Generate a new method. this.context.GenerateCode(); // Add the generated method to the nested function list. if (optimizationInfo.NestedFunctions == null) { optimizationInfo.NestedFunctions = new List <GeneratedMethod>(); } optimizationInfo.NestedFunctions.Add(this.context.GeneratedMethod); // Add all the nested methods to the parent list. if (this.context.GeneratedMethod.Dependencies != null) { foreach (var nestedFunctionExpression in this.context.GeneratedMethod.Dependencies) { optimizationInfo.NestedFunctions.Add(nestedFunctionExpression); } } // Store the generated method in the cache. long generatedMethodID = GeneratedMethod.Save(this.context.GeneratedMethod); // Create a UserDefinedFunction. // prototype EmitHelpers.LoadScriptEngine(generator); generator.Call(ReflectionHelpers.ScriptEngine_Function); generator.Call(ReflectionHelpers.FunctionInstance_InstancePrototype); // name string prefix = null; if (Name.IsGetter) { prefix = "get "; } else if (Name.IsSetter) { prefix = "set "; } if (Name.HasStaticName) { generator.LoadString(prefix + Name.StaticName); } else { // Compute the name at runtime. if (prefix != null) { generator.LoadString(prefix); } Name.ComputedName.GenerateCode(generator, optimizationInfo); EmitConversion.ToString(generator, Name.ComputedName.ResultType); if (prefix != null) { generator.CallStatic(ReflectionHelpers.String_Concat_String_String); } } // argumentNames generator.LoadInt32(this.Arguments.Count); generator.NewArray(typeof(string)); for (int i = 0; i < this.Arguments.Count; i++) { generator.Duplicate(); generator.LoadInt32(i); generator.LoadString(this.Arguments[i].Name); generator.StoreArrayElement(typeof(string)); } // scope Scope.GenerateReference(generator, optimizationInfo); // bodyText generator.LoadString(this.BodyText); // body generator.LoadInt64(generatedMethodID); generator.Call(ReflectionHelpers.GeneratedMethod_Load); // strictMode generator.LoadBoolean(this.context.StrictMode); // container if (ContainerVariable != null) { generator.LoadVariable(ContainerVariable); } else { generator.LoadNull(); } // CreateFunction(ObjectInstance prototype, string name, IList<string> argumentNames, // RuntimeScope scope, Func<Scope, object, object[], object> body, // bool strictMode, FunctionInstance container) generator.CallStatic(ReflectionHelpers.ReflectionHelpers_CreateFunction); }