/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dm; ILGenerator generator; if (ScriptEngine.LowPrivilegeEnvironment == false) { // Full trust only - skips visibility checks. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. generator = new DynamicILGenerator(dm); } else { // Partial trust / silverlight. dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }); // Parameter types of the generated method. generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); } // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return((BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate))); }
/// <summary> /// Creates a new label instance. /// </summary> /// <param name="generator"> The generator that created this label. </param> /// <param name="identifier"> The label identifier (must be unique within a method). </param> public DynamicILLabel(DynamicILGenerator generator, int identifier) { if (identifier < 0) { throw new ArgumentOutOfRangeException("identifier"); } this.ILGenerator = generator; this.Identifier = identifier; this.ILOffset = -1; #if !DEBUG this.EvaluationStackSize = -1; #endif }
/// <summary> /// Creates a new local variable instance. /// </summary> /// <param name="generator"> The generator that created this variable. </param> /// <param name="index"> The index of the local variable within the method body. </param> /// <param name="type"> The type of the variable. </param> /// <param name="name"> The name of the local variable. Can be <c>null</c>. </param> public DynamicILLocalVariable(DynamicILGenerator generator, int index, Type type, string name) { if (index < 0) { throw new ArgumentOutOfRangeException("index"); } if (type == null) { throw new ArgumentNullException("type"); } this.ILGenerator = generator; this.index = index; this.type = type; this.name = name; }
/// <summary> /// Creates a delegate that does type conversion and calls the bound method. /// </summary> /// <param name="argumentCount"> The number of arguments that will be passed to the delegate. </param> /// <returns> A delegate that does type conversion and calls the method represented by this /// object. </returns> /// <remarks> No caching of the result occurs. </remarks> private BinderDelegate CreateDelegateCore(int argumentCount) { // Create a new dynamic method. // Full trust only - skips visibility checks. System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod( string.Format("binder_for_{0}", this.FullName), // Name of the generated method. typeof(object), // Return type of the generated method. new Type[] { typeof(ScriptEngine), typeof(object), typeof(object[]) }, // Parameter types of the generated method. typeof(JSBinder), // Owner type. true); // Skips visibility checks. ILGenerator generator; #if __MonoCS__ generator = new ReflectionEmitILGenerator(dm.GetILGenerator()); #else generator = new DynamicILGenerator(dm); #endif // Generate the body of the method. GenerateStub(generator, argumentCount); // Convert the DynamicMethod to a delegate. return((BinderDelegate)dm.CreateDelegate(typeof(BinderDelegate))); }
/// <summary> /// Generates IL for the script. /// </summary> public void GenerateCode() { // Generate the abstract syntax tree if it hasn't already been generated. if (this.AbstractSyntaxTree == null) { Parse(); Optimize(); } // Initialize global code-gen information. var optimizationInfo = new OptimizationInfo(this.Engine); optimizationInfo.AbstractSyntaxTree = this.AbstractSyntaxTree; optimizationInfo.StrictMode = this.StrictMode; optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints; optimizationInfo.FunctionName = this.GetStackName(); optimizationInfo.Source = this.Source; ILGenerator generator; if (this.Options.EnableDebugging == false) { // DynamicMethod requires full trust because of generator.LoadMethodPointer in the // FunctionExpression class. // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dynamicMethod; #if !SILVERLIGHT if (ScriptEngine.LowPrivilegeEnvironment == false) { // High privilege path. dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes(), // Parameter types of the generated method. typeof(MethodGenerator), // Owner type. true); // Skip visibility checks. // TODO: Figure out why long methods give BadImageFormatException in .NET 3.5 when generated using DynamicILInfo. if (Environment.Version.Major >= 4) { generator = new DynamicILGenerator(dynamicMethod); } else { generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator()); } } else { #endif // Low privilege path. dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes()); // Parameter types of the generated method. generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator()); #if !SILVERLIGHT } #endif if (this.Engine.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } // Initialization code will appear to come from line 1. optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1)); // Generate the IL. GenerateCode(generator, optimizationInfo); generator.Complete(); // Create a delegate from the method. this.GeneratedMethod = new GeneratedMethod(dynamicMethod.CreateDelegate(GetDelegate()), optimizationInfo.NestedFunctions); } else { #if WINDOWS_PHONE throw new NotImplementedException(); #else // Debugging or low trust path. ScriptEngine.ReflectionEmitModuleInfo reflectionEmitInfo = this.Engine.ReflectionEmitInfo; if (reflectionEmitInfo == null) { reflectionEmitInfo = new ScriptEngine.ReflectionEmitModuleInfo(); // Create a dynamic assembly and module. reflectionEmitInfo.AssemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly( new System.Reflection.AssemblyName("Jurassic Dynamic Assembly"), System.Reflection.Emit.AssemblyBuilderAccess.Run); // Mark the assembly as debuggable. This must be done before the module is created. var debuggableAttributeConstructor = typeof(System.Diagnostics.DebuggableAttribute).GetConstructor( new Type[] { typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes) }); reflectionEmitInfo.AssemblyBuilder.SetCustomAttribute( new System.Reflection.Emit.CustomAttributeBuilder(debuggableAttributeConstructor, new object[] { System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations | System.Diagnostics.DebuggableAttribute.DebuggingModes.Default })); // Create a dynamic module. reflectionEmitInfo.ModuleBuilder = reflectionEmitInfo.AssemblyBuilder.DefineDynamicModule("Module", this.Options.EnableDebugging); this.Engine.ReflectionEmitInfo = reflectionEmitInfo; } // Create a new type to hold our method. var typeBuilder = reflectionEmitInfo.ModuleBuilder.DefineType("JavaScriptClass" + reflectionEmitInfo.TypeCount.ToString(), System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class); reflectionEmitInfo.TypeCount++; // Create a method. var methodBuilder = typeBuilder.DefineMethod(this.GetMethodName(), System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public, typeof(object), GetParameterTypes()); // Generate the IL for the method. generator = new ReflectionEmitILGenerator(methodBuilder.GetILGenerator()); if (this.Engine.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } if (this.Source.Path != null && this.Options.EnableDebugging == true) { // Initialize the debugging information. optimizationInfo.DebugDocument = reflectionEmitInfo.ModuleBuilder.DefineDocument(this.Source.Path, COMHelpers.LanguageType, COMHelpers.LanguageVendor, COMHelpers.DocumentType); methodBuilder.DefineParameter(1, System.Reflection.ParameterAttributes.None, "scriptEngine"); methodBuilder.DefineParameter(2, System.Reflection.ParameterAttributes.None, "scope"); methodBuilder.DefineParameter(3, System.Reflection.ParameterAttributes.None, "thisValue"); } optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1)); GenerateCode(generator, optimizationInfo); generator.Complete(); // Bake it. var type = typeBuilder.CreateType(); var methodInfo = type.GetMethod(this.GetMethodName()); this.GeneratedMethod = new GeneratedMethod(Delegate.CreateDelegate(GetDelegate(), methodInfo), optimizationInfo.NestedFunctions); #endif //WINDOWS_PHONE } if (this.Engine.EnableILAnalysis == true) { // Store the disassembled IL so it can be retrieved for analysis purposes. this.GeneratedMethod.DisassembledIL = generator.ToString(); } }
/// <summary> /// Generates IL for the script. /// </summary> public void GenerateCode() { // Generate the abstract syntax tree if it hasn't already been generated. if (this.AbstractSyntaxTree == null) { Parse(); Optimize(); } // Initialize global code-gen information. var optimizationInfo = new OptimizationInfo(); optimizationInfo.AbstractSyntaxTree = this.AbstractSyntaxTree; optimizationInfo.StrictMode = this.StrictMode; optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints; optimizationInfo.FunctionName = this.GetStackName(); optimizationInfo.Source = this.Source; ILGenerator generator; if (this.Options.EnableDebugging == false) { // DynamicMethod requires full trust because of generator.LoadMethodPointer in the // FunctionExpression class. // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes(), // Parameter types of the generated method. typeof(MethodGenerator), // Owner type. true); // Skip visibility checks. #if USE_DYNAMIC_IL_INFO generator = new DynamicILGenerator(dynamicMethod); #else generator = new ReflectionEmitILGenerator(dynamicMethod.GetILGenerator(), emitDebugInfo: false); #endif if (this.Options.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } // Initialization code will appear to come from line 1. optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1)); // Generate the IL. GenerateCode(generator, optimizationInfo); generator.Complete(); // Create a delegate from the method. this.GeneratedMethod = new GeneratedMethod(dynamicMethod.CreateDelegate(GetDelegate()), optimizationInfo.NestedFunctions); } else { #if ENABLE_DEBUGGING // Debugging or low trust path. ReflectionEmitModuleInfo reflectionEmitInfo; System.Reflection.Emit.TypeBuilder typeBuilder; lock (reflectionEmitInfoLock) { reflectionEmitInfo = ReflectionEmitInfo; if (reflectionEmitInfo == null) { reflectionEmitInfo = new ReflectionEmitModuleInfo(); // Create a dynamic assembly and module. reflectionEmitInfo.AssemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly( new System.Reflection.AssemblyName("Jurassic Dynamic Assembly"), System.Reflection.Emit.AssemblyBuilderAccess.Run); // Mark the assembly as debuggable. This must be done before the module is created. var debuggableAttributeConstructor = typeof(System.Diagnostics.DebuggableAttribute).GetConstructor( new Type[] { typeof(System.Diagnostics.DebuggableAttribute.DebuggingModes) }); reflectionEmitInfo.AssemblyBuilder.SetCustomAttribute( new System.Reflection.Emit.CustomAttributeBuilder(debuggableAttributeConstructor, new object[] { System.Diagnostics.DebuggableAttribute.DebuggingModes.DisableOptimizations | System.Diagnostics.DebuggableAttribute.DebuggingModes.Default })); // Create a dynamic module. reflectionEmitInfo.ModuleBuilder = reflectionEmitInfo.AssemblyBuilder.DefineDynamicModule("Module", this.Options.EnableDebugging); ReflectionEmitInfo = reflectionEmitInfo; } // Create a new type to hold our method. typeBuilder = reflectionEmitInfo.ModuleBuilder.DefineType("JavaScriptClass" + reflectionEmitInfo.TypeCount.ToString(), System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class); reflectionEmitInfo.TypeCount++; } // Create a method. var methodBuilder = typeBuilder.DefineMethod(this.GetMethodName(), System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public, typeof(object), GetParameterTypes()); // Generate the IL for the method. generator = new ReflectionEmitILGenerator(methodBuilder.GetILGenerator(), emitDebugInfo: true); if (this.Options.EnableILAnalysis == true) { // Replace the generator with one that logs. generator = new LoggingILGenerator(generator); } if (this.Source.Path != null && this.Options.EnableDebugging == true) { // Initialize the debugging information. optimizationInfo.DebugDocument = reflectionEmitInfo.ModuleBuilder.DefineDocument(this.Source.Path, LanguageType, LanguageVendor, DocumentType); var parameterNames = GetParameterNames(); for (var i = 0; i < parameterNames.Length; i++) { methodBuilder.DefineParameter(i + 1, System.Reflection.ParameterAttributes.In, parameterNames[i]); } } optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1)); GenerateCode(generator, optimizationInfo); generator.Complete(); // Bake it. var type = typeBuilder.CreateType(); var methodInfo = type.GetMethod(this.GetMethodName()); this.GeneratedMethod = new GeneratedMethod(Delegate.CreateDelegate(GetDelegate(), methodInfo), optimizationInfo.NestedFunctions); #else throw new NotImplementedException(); #endif // ENABLE_DEBUGGING } if (this.Options.EnableILAnalysis == true) { // Store the disassembled IL so it can be retrieved for analysis purposes. this.GeneratedMethod.DisassembledIL = generator.ToString(); } }
/// <summary> /// Generates IL for the script. /// </summary> public void GenerateCode() { // Generate the abstract syntax tree if it hasn't already been generated. if (this.AbstractSyntaxTree == null) { Parse(); Optimize(); } // Initialize global code-gen information. var optimizationInfo = new OptimizationInfo(); optimizationInfo.AbstractSyntaxTree = this.AbstractSyntaxTree; optimizationInfo.StrictMode = this.StrictMode; optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints; optimizationInfo.FunctionName = this.GetStackName(); optimizationInfo.Source = this.Source; // DynamicMethod requires full trust because of generator.LoadMethodPointer in the // FunctionExpression class. // Create a new dynamic method. System.Reflection.Emit.DynamicMethod dynamicMethod = new System.Reflection.Emit.DynamicMethod( GetMethodName(), // Name of the generated method. typeof(object), // Return type of the generated method. GetParameterTypes(), // Parameter types of the generated method. typeof(MethodGenerator), // Owner type. true); // Skip visibility checks. #if USE_DYNAMIC_IL_INFO ILGenerator generator = new DynamicILGenerator(dynamicMethod); #else ILGenerator generator = new ReflectionEmitILGenerator(dynamicMethod, emitDebugInfo: false); #endif ILGenerator loggingILGenerator = null; if (this.Options.EnableILAnalysis) { // Replace the generator with one that logs. generator = loggingILGenerator = new LoggingILGenerator(generator); } #if DEBUG // Replace the generator with one that verifies correctness. generator = new VerifyingILGenerator(generator); #endif // Initialization code will appear to come from line 1. optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1)); // Generate the IL. GenerateCode(generator, optimizationInfo); generator.Complete(); // Create a delegate from the method. this.GeneratedMethod = new GeneratedMethod(dynamicMethod.CreateDelegate(GetDelegate()), optimizationInfo.NestedFunctions); if (loggingILGenerator != null) { // Store the disassembled IL so it can be retrieved for analysis purposes. this.GeneratedMethod.DisassembledIL = loggingILGenerator.ToString(); } }