コード例 #1
0
ファイル: ScriptEngine.cs プロジェクト: richardbang83/GNet
        private void VerifyGeneratedCode()
        {
#if false
            if (this.EnableDebugging == false)
            {
                return;
            }

            var filePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "JurassicDebug.dll");

            // set the entry point for the application and save it
            this.ReflectionEmitInfo.AssemblyBuilder.Save(System.IO.Path.GetFileName(filePath));

            // Copy this DLL there as well.
            var assemblyPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
            System.IO.File.Copy(assemblyPath, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(filePath), System.IO.Path.GetFileName(assemblyPath)), true);

            var startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName               = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\PEVerify.exe";
            startInfo.Arguments              = string.Format("\"{0}\" /nologo /verbose /unique", filePath);
            startInfo.CreateNoWindow         = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.UseShellExecute        = false;
            var    verifyProcess = System.Diagnostics.Process.Start(startInfo);
            string output        = verifyProcess.StandardOutput.ReadToEnd();

            if (verifyProcess.ExitCode != 0)
            {
                throw new InvalidOperationException(output);
            }
            //else
            //{
            //    System.Diagnostics.Process.Start(@"C:\Program Files\Reflector\Reflector.exe", string.Format("\"{0}\" /select:JavaScriptClass", filePath));
            //    Environment.Exit(0);
            //}

            // The assembly can no longer be modified - so don't use it again.
            this.ReflectionEmitInfo = null;
#endif
        }
コード例 #2
0
ファイル: Prototype.cs プロジェクト: Bablakeluke/Nitrassic
        internal Prototype(ScriptEngine engine, string name, Prototype baseProto, bool isStatic)
        {
            Engine        = engine;
            BasePrototype = baseProto;
            IsStatic      = isStatic;

            ReflectionEmitModuleInfo moduleInfo = engine.ReflectionEmitInfo;

            if (name == null)
            {
                name = "__proto__" + moduleInfo.TypeCount;
                moduleInfo.TypeCount++;
            }

            Name = name;

            Type baseType;

            if (baseProto == null)
            {
                baseType = typeof(object);
            }
            else
            {
                baseType = baseProto.Type;
            }

            // Define the type now; note that methods are not declared on these (JS defined methods are always static):
            Builder = moduleInfo.ModuleBuilder.DefineType(name,
                                                          System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class, baseType
                                                          );

            if (!isStatic)
            {
                // Define the default ctr and obtain it:
                AddConstructor(Builder.DefineDefaultConstructor(System.Reflection.MethodAttributes.Public));
            }
        }
コード例 #3
0
        /// <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();
            }
        }
コード例 #4
0
        /// <summary>
        /// Generates IL for a specific variant of the method. Arguments MUST include 'this' keyword.
        /// </summary>
        public UserDefinedFunction GenerateCode(ArgVariable[] arguments, OptimizationInfo optimizationInfo)
        {
            // Generate the abstract syntax tree if it hasn't already been generated.
            if (this.AbstractSyntaxTree == null)
            {
                Parse(optimizationInfo);

                Dependencies = optimizationInfo.NestedFunctions;
            }

            // Create the param types, which is the args (as they already include 'this'):
            int argCount = arguments == null?0 : arguments.Length;

            Type[] parameters = new Type[argCount];

            for (int i = 0; i < argCount; i++)
            {
                // Transfer the type over:
                parameters[i] = arguments[i].Type;
            }

            string name = GetMethodName();

            // Initialize global code-gen information.
            optimizationInfo.AbstractSyntaxTree      = this.AbstractSyntaxTree;
            optimizationInfo.StrictMode              = this.StrictMode;
            optimizationInfo.MethodOptimizationHints = this.MethodOptimizationHints;
            optimizationInfo.FunctionName            = this.GetStackName();
            optimizationInfo.Source = this.Source;

            ILGenerator generator;

            // Create the UDF now (must be before we generate the code as it would go recursive for recursive functions otherwise):
            UserDefinedFunction mtd = new UserDefinedFunction(name, arguments, this as FunctionMethodGenerator, StrictMode);

            // Add to created set:
            GeneratedMethods.Add(mtd);

            // Clear locals:
            if (InitialScope != null)
            {
                InitialScope.Reset();
            }

            // Resolve variables now:
            AbstractSyntaxTree.ResolveVariables(optimizationInfo);

            // Low trust path.
            ReflectionEmitModuleInfo reflectionEmitInfo = this.Engine.ReflectionEmitInfo;

            var typeBuilder = reflectionEmitInfo.MainType;

            // Create the method builder now:
            var methodBuilder = typeBuilder.DefineMethod(name,
                                                         System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public,
                                                         optimizationInfo.ReturnType, parameters);

            mtd.body = methodBuilder;

            // Generate the IL for the method.
            generator = new ReflectionEmitILGenerator(Engine, methodBuilder);

            if (ScriptEngine.EnableILAnalysis)
            {
                // Replace the generator with one that logs.
                generator = new LoggingILGenerator(generator);
            }

            // optimizationInfo.MarkSequencePoint(generator, new SourceCodeSpan(1, 1, 1, 1));
            GenerateCode(arguments, generator, optimizationInfo);
            generator.Complete();

            if (ScriptEngine.EnableILAnalysis)
            {
                // Store the disassembled IL so it can be retrieved for analysis purposes.
                mtd.DisassembledIL = generator.ToString();

                string args = "";

                if (arguments != null)
                {
                    for (int i = 0; i < arguments.Length; i++)
                    {
                        if (i != 0)
                        {
                            args += ",";
                        }
                        args += parameters[i] + " " + arguments[i].Name.ToString();
                    }
                }

                Engine.Log("-IL " + GetMethodName() + "(" + args + ") : " + methodBuilder.ReturnType + "-");
                Engine.Log(mtd.DisassembledIL);
            }

            return(mtd);
        }