aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL
diff options
context:
space:
mode:
authorTedd Hansen2008-02-02 02:35:56 +0000
committerTedd Hansen2008-02-02 02:35:56 +0000
commit8ccc12d642d1104bf4c1249a02a82d8af5d6efe0 (patch)
treef3691396c5649dbfc393b289cf7b5224cb251c85 /OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL
parentAdded OpenSim.32BitLaunch.exe that can be used on 64-bit systems to run OpenS... (diff)
downloadopensim-SC-8ccc12d642d1104bf4c1249a02a82d8af5d6efe0.zip
opensim-SC-8ccc12d642d1104bf4c1249a02a82d8af5d6efe0.tar.gz
opensim-SC-8ccc12d642d1104bf4c1249a02a82d8af5d6efe0.tar.bz2
opensim-SC-8ccc12d642d1104bf4c1249a02a82d8af5d6efe0.tar.xz
Added OpenSim.32BitLaunch.exe that can be used on 64-bit systems to run OpenSim in 32-bit mode.
Added VISUAL BASIC.NET-support //cs, //lsl and //vb as first characters of script will determine what compiler is used. Compile warnings are no longer treated as errors. Script will still run. Added a few useless and useful config options: Write script source to harddisk for debug, Default compile language, Allowed compilers (languages), compile in release or debug mode, clean up old scripts on startup Loads of warnings for incorrect config
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs255
1 files changed, 222 insertions, 33 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
index 2adc060..d3f2873 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
@@ -28,9 +28,12 @@
28 28
29using System; 29using System;
30using System.CodeDom.Compiler; 30using System.CodeDom.Compiler;
31using System.Collections.Generic;
32using System.Globalization;
31using System.IO; 33using System.IO;
32using System.Reflection; 34using System.Reflection;
33using Microsoft.CSharp; 35using Microsoft.CSharp;
36using Microsoft.VisualBasic;
34 37
35namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL 38namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
36{ 39{
@@ -44,45 +47,192 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
44 // Assembly is compiled using LSL_BaseClass as base. Look at debug C# code file created when LSL script is compiled for full details. 47 // Assembly is compiled using LSL_BaseClass as base. Look at debug C# code file created when LSL script is compiled for full details.
45 // 48 //
46 49
47 private LSL2CSConverter LSL_Converter = new LSL2CSConverter(); 50 internal enum enumCompileType
48 private CSharpCodeProvider codeProvider = new CSharpCodeProvider(); 51 {
52 lsl = 0,
53 cs = 1,
54 vb = 2
55 }
56 private enumCompileType DefaultCompileLanguage;
57 private bool WriteScriptSourceToDebugFile;
58 private bool CompileWithDebugInformation;
59 private bool CleanUpOldScriptsOnStartup;
60 private System.Collections.Generic.Dictionary<string, Boolean> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
61 private System.Collections.Generic.Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
62
63 private string FilePrefix;
64 private string ScriptEnginesPath = "ScriptEngines";
65
66 private static LSL2CSConverter LSL_Converter = new LSL2CSConverter();
67 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
68 private static VBCodeProvider VBcodeProvider = new VBCodeProvider();
69
49 private static UInt64 scriptCompileCounter = 0; 70 private static UInt64 scriptCompileCounter = 0;
50 71
51 private static int instanceID = new Random().Next(0, int.MaxValue); 72 private static int instanceID = new Random().Next(0, int.MaxValue);
52 // Implemented due to peer preassure --- will cause garbage in ScriptEngines folder ;) 73 // Implemented due to peer preassure --- will cause garbage in ScriptEngines folder ;)
53 74
54 //private ICodeCompiler icc = codeProvider.CreateCompiler(); 75 public Common.ScriptEngineBase.ScriptEngine m_scriptEngine;
55 public string CompileFromFile(string LSOFileName) 76 public Compiler(Common.ScriptEngineBase.ScriptEngine scriptEngine)
56 { 77 {
57 switch (Path.GetExtension(LSOFileName).ToLower()) 78 m_scriptEngine = scriptEngine;
58 { 79 ReadConfig();
59 case ".txt": 80 }
60 case ".lsl": 81 public bool in_startup = true;
61 Common.ScriptEngineBase.Common.SendToDebug("Source code is LSL, converting to CS"); 82 public void ReadConfig()
62 return CompileFromLSLText(File.ReadAllText(LSOFileName)); 83 {
63 case ".cs": 84 WriteScriptSourceToDebugFile = m_scriptEngine.ScriptConfigSource.GetBoolean("WriteScriptSourceToDebugFile", true);
64 Common.ScriptEngineBase.Common.SendToDebug("Source code is CS"); 85 CompileWithDebugInformation = m_scriptEngine.ScriptConfigSource.GetBoolean("CompileWithDebugInformation", true);
65 return CompileFromCSText(File.ReadAllText(LSOFileName)); 86 CleanUpOldScriptsOnStartup = m_scriptEngine.ScriptConfigSource.GetBoolean("CleanUpOldScriptsOnStartup", true);
66 default: 87
67 throw new Exception("Unknown script type."); 88 // Get file prefix from scriptengine name and make it file system safe:
89 FilePrefix = m_scriptEngine.ScriptEngineName;
90 foreach (char c in Path.GetInvalidFileNameChars())
91 {
92 FilePrefix = FilePrefix.Replace(c, '_');
93 }
94 // First time we start?
95 if (in_startup)
96 {
97 in_startup = false;
98 DeleteOldFiles();
99 }
100
101 LanguageMapping.Add("cs", enumCompileType.cs);
102 LanguageMapping.Add("vb", enumCompileType.lsl);
103 LanguageMapping.Add("lsl", enumCompileType.vb);
104
105 // Allowed compilers
106 string allowedCompilers = m_scriptEngine.ScriptConfigSource.GetString("AllowedCompilers", "lsl;cs;vb");
107 AllowedCompilers.Clear();
108 foreach (string strl in allowedCompilers.Split(';'))
109 {
110 string strlan = strl.Trim(" \t".ToCharArray()).ToLower();
111 if (!LanguageMapping.ContainsKey(strlan))
112 {
113 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Config error. Compiler is unable to recongnize language type \"" + strl + "\" specified in \"AllowedCompilers\".");
114 }
115 AllowedCompilers.Add(strlan, true);
116 }
117 if (AllowedCompilers.Count == 0)
118 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Config error. Compiler could not recognize any language in \"AllowedCompilers\". Scripts will not be executed!");
119
120 // Default language
121 string defaultCompileLanguage = m_scriptEngine.ScriptConfigSource.GetString("DefaultCompileLanguage", "lsl").ToLower();
122
123 // Is this language recognized at all?
124 if (!LanguageMapping.ContainsKey(defaultCompileLanguage))
125 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Config error. Default language specified in \"DefaultCompileLanguage\" is not recognized as a valid language. Scripts may not be executed!");
126
127 // Is this language in allow-list?
128 if (!AllowedCompilers.ContainsKey(defaultCompileLanguage))
129 {
130 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName,
131 "Config error. Default language \"" + defaultCompileLanguage + "\"specified in \"DefaultCompileLanguage\" is not in list of \"AllowedCompilers\". Scripts may not be executed!");
132 }
133 else
134 {
135 // LANGUAGE IS IN ALLOW-LIST
136 DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage];
137 }
138
139 // We now have an allow-list, a mapping list, and a default language
140
141 }
142
143 private void DeleteOldFiles()
144 {
145
146 // CREATE FOLDER IF IT DOESNT EXIST
147 if (!Directory.Exists(ScriptEnginesPath))
148 {
149 try
150 {
151 Directory.CreateDirectory(ScriptEnginesPath);
152 }
153 catch (Exception ex)
154 {
155 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Exception trying to create ScriptEngine directory \"" + ScriptEnginesPath + "\": " + ex.ToString());
156 }
157 }
158
159 foreach (string file in Directory.GetFiles(ScriptEnginesPath))
160 {
161 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "FILE FOUND: " + file);
162
163 if (file.ToLower().StartsWith(FilePrefix + "_compiled_") ||
164 file.ToLower().StartsWith(FilePrefix + "_source_"))
165 {
166 try
167 {
168 File.Delete(file);
169 }
170 catch (Exception ex)
171 {
172 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Exception trying delete old script file \"" + file + "\": " + ex.ToString());
173 }
174
175 }
68 } 176 }
177
69 } 178 }
70 179
180 ////private ICodeCompiler icc = codeProvider.CreateCompiler();
181 //public string CompileFromFile(string LSOFileName)
182 //{
183 // switch (Path.GetExtension(LSOFileName).ToLower())
184 // {
185 // case ".txt":
186 // case ".lsl":
187 // Common.ScriptEngineBase.Common.SendToDebug("Source code is LSL, converting to CS");
188 // return CompileFromLSLText(File.ReadAllText(LSOFileName));
189 // case ".cs":
190 // Common.ScriptEngineBase.Common.SendToDebug("Source code is CS");
191 // return CompileFromCSText(File.ReadAllText(LSOFileName));
192 // default:
193 // throw new Exception("Unknown script type.");
194 // }
195 //}
196
71 /// <summary> 197 /// <summary>
72 /// Converts script from LSL to CS and calls CompileFromCSText 198 /// Converts script from LSL to CS and calls CompileFromCSText
73 /// </summary> 199 /// </summary>
74 /// <param name="Script">LSL script</param> 200 /// <param name="Script">LSL script</param>
75 /// <returns>Filename to .dll assembly</returns> 201 /// <returns>Filename to .dll assembly</returns>
76 public string CompileFromLSLText(string Script) 202 public string PerformScriptCompile(string Script)
77 { 203 {
78 if (Script.Substring(0, 4).ToLower() == "//c#") 204 enumCompileType l = DefaultCompileLanguage;
205
206
207 if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture))
208 l = enumCompileType.cs;
209 if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture))
210 l = enumCompileType.vb;
211 if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture))
212 l = enumCompileType.lsl;
213
214 if (!AllowedCompilers.ContainsKey(l.ToString()))
215 {
216 // Not allowed to compile to this language!
217 string errtext = String.Empty;
218 errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!";
219 throw new Exception(errtext);
220 }
221
222 string compileScript;
223
224 if (l == enumCompileType.lsl)
79 { 225 {
80 return CompileFromCSText(Script); 226 // Its LSL, convert it to C#
227 compileScript = LSL_Converter.Convert(Script);
228 l = enumCompileType.cs;
81 } 229 }
82 else 230 else
83 { 231 {
84 return CompileFromCSText(LSL_Converter.Convert(Script)); 232 // We don't need to convert
233 compileScript = Script;
85 } 234 }
235 return CompileFromCSorVBText(Script, l);
86 } 236 }
87 237
88 /// <summary> 238 /// <summary>
@@ -90,36 +240,45 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
90 /// </summary> 240 /// </summary>
91 /// <param name="Script">CS script</param> 241 /// <param name="Script">CS script</param>
92 /// <returns>Filename to .dll assembly</returns> 242 /// <returns>Filename to .dll assembly</returns>
93 public string CompileFromCSText(string Script) 243 internal string CompileFromCSorVBText(string Script, enumCompileType lang)
94 { 244 {
245 string ext = "." + lang.ToString();
246
95 // Output assembly name 247 // Output assembly name
96 scriptCompileCounter++; 248 scriptCompileCounter++;
97 string OutFile = 249 string OutFile =
98 Path.Combine("ScriptEngines", 250 Path.Combine("ScriptEngines",
99 "DotNetScript_" + instanceID.ToString() + "_" + scriptCompileCounter.ToString() + ".dll"); 251 FilePrefix + "_compiled_" + instanceID.ToString() + "_" + scriptCompileCounter.ToString() + ".dll");
100 try 252 try
101 { 253 {
102 File.Delete(OutFile); 254 File.Delete(OutFile);
103 } 255 }
104 catch (Exception e) 256 catch (Exception e)
105 { 257 {
106 Console.WriteLine("Exception attempting to delete old compiled script: " + e.ToString()); 258 //m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
259 throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
107 } 260 }
108 //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll"); 261 //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
109 262
110 // DEBUG - write source to disk 263 // DEBUG - write source to disk
111 try 264 if (WriteScriptSourceToDebugFile)
112 {
113 File.WriteAllText(
114 Path.Combine("ScriptEngines", "debug_" + Path.GetFileNameWithoutExtension(OutFile) + ".cs"), Script);
115 }
116 catch
117 { 265 {
266 try
267 {
268 File.WriteAllText(
269 Path.Combine("ScriptEngines", FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext),
270 Script);
271 }
272 catch
273 {
274 }
118 } 275 }
119 276
120 // Do actual compile 277 // Do actual compile
121 CompilerParameters parameters = new CompilerParameters(); 278 CompilerParameters parameters = new CompilerParameters();
279
122 parameters.IncludeDebugInformation = true; 280 parameters.IncludeDebugInformation = true;
281
123 // Add all available assemblies 282 // Add all available assemblies
124 foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) 283 foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
125 { 284 {
@@ -136,11 +295,29 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
136 //parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment"); 295 //parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
137 parameters.GenerateExecutable = false; 296 parameters.GenerateExecutable = false;
138 parameters.OutputAssembly = OutFile; 297 parameters.OutputAssembly = OutFile;
139 parameters.IncludeDebugInformation = false; 298 parameters.IncludeDebugInformation = CompileWithDebugInformation;
140 CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, Script); 299 parameters.WarningLevel = 4;
300 parameters.TreatWarningsAsErrors = false;
141 301
302 CompilerResults results;
303 switch (lang)
304 {
305 case enumCompileType.vb:
306 results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script);
307 break;
308 case enumCompileType.cs:
309 results = CScodeProvider.CompileAssemblyFromSource(parameters, Script);
310 break;
311 default:
312 throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\"");
313 }
314
315 // Check result
142 // Go through errors 316 // Go through errors
143 // TODO: Return errors to user somehow 317
318 //
319 // WARNINGS AND ERRORS
320 //
144 if (results.Errors.Count > 0) 321 if (results.Errors.Count > 0)
145 { 322 {
146 string errtext = String.Empty; 323 string errtext = String.Empty;
@@ -150,10 +327,22 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
150 ", Error Number: " + CompErr.ErrorNumber + 327 ", Error Number: " + CompErr.ErrorNumber +
151 ", '" + CompErr.ErrorText + "'\r\n"; 328 ", '" + CompErr.ErrorText + "'\r\n";
152 } 329 }
153 throw new Exception(errtext); 330 if (!File.Exists(OutFile))
331 {
332 throw new Exception(errtext);
333 }
154 } 334 }
155 335
156 336
337 //
338 // NO ERRORS, BUT NO COMPILED FILE
339 //
340 if (!File.Exists(OutFile))
341 {
342 string errtext = String.Empty;
343 errtext += "No compile error. But not able to locate compiled file.";
344 throw new Exception(errtext);
345 }
157 return OutFile; 346 return OutFile;
158 } 347 }
159 } 348 }