aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs')
-rw-r--r--OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs186
1 files changed, 186 insertions, 0 deletions
diff --git a/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs
new file mode 100644
index 0000000..e221e1b
--- /dev/null
+++ b/OpenSim/ScriptEngine/Components/DotNetEngine/Compilers/CILCompiler.cs
@@ -0,0 +1,186 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.CodeDom.Compiler;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text.RegularExpressions;
33using log4net;
34using OpenSim.ScriptEngine.Shared;
35using ScriptAssemblies;
36
37namespace OpenSim.ScriptEngine.Components.DotNetEngine.Compilers
38{
39 public abstract class CILCompiler
40 {
41 internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 private string ScriptEnginesPath = "ScriptEngines";
43 private string Name { get { return "SECS.DotNetEngine.CILCompiler"; } }
44 internal string ScriptAssemblyName { get; set; }
45
46 // Default inherit
47 protected string ScriptInheritFrom = typeof(ScriptAssemblies.ScriptBase).Name;
48 private readonly System.Security.Cryptography.MD5CryptoServiceProvider MD5Sum = new System.Security.Cryptography.MD5CryptoServiceProvider();
49 protected CodeDomProvider CompileProvider;
50
51 //private string[] AppDomainAssemblies = new string[] { "OpenSim.Region.ScriptEngine.Shared.dll", "OpenSim.Region.ScriptEngine.Shared.Script.dll", "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll" };
52 private readonly string[] AppDomainAssemblies = new string[] {
53 Assembly.GetAssembly(typeof(Int32)).Location,
54 "OpenSim.ScriptEngine.Shared.dll",
55 "OpenSim.ScriptEngine.Shared.Script.dll",
56 Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine.Shared.dll")
57 };
58
59 public abstract string PreProcessScript(ref string script);
60
61 public CILCompiler()
62 {
63 }
64
65 private static readonly Regex FileNameFixer = new Regex(@"[^a-zA-Z0-9\.\-]", RegexOptions.Compiled | RegexOptions.Singleline);
66 public string Compile(ScriptMetaData data, ref string _script)
67 {
68 // Add "using", "inherit", default constructor, etc around script.
69 string script = PreProcessScript(ref _script);
70
71 // Get filename based on content
72 string md5Sum = System.Convert.ToBase64String(
73 MD5Sum.ComputeHash(
74 System.Text.Encoding.ASCII.GetBytes(script)
75 ));
76 // Unique name for this assembly
77 ScriptAssemblyName = "SECS_Script_" + FileNameFixer.Replace(md5Sum, "_");
78
79 string OutFile = Path.Combine(ScriptEnginesPath, ScriptAssemblyName + ".dll");
80
81 // Make sure target dir exist
82 if (!Directory.Exists(ScriptEnginesPath))
83 try { Directory.CreateDirectory(ScriptEnginesPath); }
84 catch { }
85
86 // Already exist? No point in recompiling
87 if (File.Exists(OutFile))
88 return OutFile;
89
90 //
91 // Dump source code
92 //
93 string dumpFile = OutFile + ".txt";
94 try
95 {
96 if (File.Exists(dumpFile))
97 File.Delete(dumpFile);
98 File.WriteAllText(dumpFile, script);
99 }
100 catch (Exception e)
101 {
102 m_log.DebugFormat("[{0}] Exception trying to dump script source code to file \"{1}\": {2}", Name, dumpFile, e.ToString());
103 }
104
105 //
106 // COMPILE
107 //
108
109 CompilerParameters parameters = new CompilerParameters();
110 parameters.IncludeDebugInformation = true;
111 string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
112
113 foreach (string file in AppDomainAssemblies)
114 {
115 parameters.ReferencedAssemblies.Add(file);
116 m_log.DebugFormat("[{0}] Adding reference for compile: \"{1}\".", Name, file);
117 }
118 //lock (commandProvider)
119 //{
120 // foreach (string key in commandProvider.Keys)
121 // {
122 // IScriptCommandProvider cp = commandProvider[key];
123 // string
124 // file = cp.GetType().Assembly.Location;
125 // parameters.ReferencedAssemblies.Add(file);
126 // m_log.DebugFormat("[{0}] Loading command provider assembly \"{1}\" into AppDomain: \"{2}\".", Name,
127 // key, file);
128 // }
129 //}
130
131 parameters.GenerateExecutable = false;
132 parameters.OutputAssembly = OutFile;
133 parameters.IncludeDebugInformation = true;
134 //parameters.WarningLevel = 1; // Should be 4?
135 parameters.TreatWarningsAsErrors = false;
136
137 // Do compile
138 CompilerResults results = CompileProvider.CompileAssemblyFromSource(parameters, script);
139
140
141 //
142 // WARNINGS AND ERRORS
143 //
144 //TODO
145 int display = 5;
146 if (results.Errors.Count > 0)
147 {
148 string errtext = String.Empty;
149 foreach (CompilerError CompErr in results.Errors)
150 {
151 // Show 5 errors max
152 //
153 if (display <= 0)
154 break;
155 display--;
156
157 string severity = "Error";
158 if (CompErr.IsWarning)
159 severity = "Warning";
160
161 //TODO: Implement
162 KeyValuePair<int, int> lslPos = new KeyValuePair<int, int>();
163
164 //lslPos = "NOT IMPLEMENTED";// FindErrorPosition(CompErr.Line, CompErr.Column);
165
166 string text = CompErr.ErrorText;
167
168 // The Second Life viewer's script editor begins
169 // countingn lines and columns at 0, so we subtract 1.
170 errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n",
171 lslPos.Key - 1, lslPos.Value - 1,
172 CompErr.ErrorNumber, text, severity);
173 }
174
175 if (!File.Exists(OutFile))
176 {
177 throw new Exception(errtext);
178 }
179 }
180
181 // TODO: Process errors
182 return OutFile;
183 }
184
185 }
186}