aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/CodeTools
diff options
context:
space:
mode:
authorDan Lake2009-10-26 07:50:25 -0700
committerJohn Hurliman2009-10-29 05:39:18 -0700
commit33448e4ba83b590e0e7e340faf3d7f2cef80c611 (patch)
tree959654ecdd83f8e78a98069b153504f92827ae12 /OpenSim/Region/ScriptEngine/Shared/CodeTools
parent* Implemented foot collision plane for avatars (diff)
downloadopensim-SC-33448e4ba83b590e0e7e340faf3d7f2cef80c611.zip
opensim-SC-33448e4ba83b590e0e7e340faf3d7f2cef80c611.tar.gz
opensim-SC-33448e4ba83b590e0e7e340faf3d7f2cef80c611.tar.bz2
opensim-SC-33448e4ba83b590e0e7e340faf3d7f2cef80c611.tar.xz
Optimizations
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs156
1 files changed, 72 insertions, 84 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index fe26429..d781a1a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -74,7 +74,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
74 private string FilePrefix; 74 private string FilePrefix;
75 private string ScriptEnginesPath = "ScriptEngines"; 75 private string ScriptEnginesPath = "ScriptEngines";
76 // mapping between LSL and C# line/column numbers 76 // mapping between LSL and C# line/column numbers
77 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
78 private ICodeConverter LSL_Converter; 77 private ICodeConverter LSL_Converter;
79 78
80 private List<string> m_warnings = new List<string>(); 79 private List<string> m_warnings = new List<string>();
@@ -91,6 +90,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
91 private static UInt64 scriptCompileCounter = 0; // And a counter 90 private static UInt64 scriptCompileCounter = 0; // And a counter
92 91
93 public IScriptEngine m_scriptEngine; 92 public IScriptEngine m_scriptEngine;
93 private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps =
94 new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>();
95
94 public Compiler(IScriptEngine scriptEngine) 96 public Compiler(IScriptEngine scriptEngine)
95 { 97 {
96 m_scriptEngine = scriptEngine; 98 m_scriptEngine = scriptEngine;
@@ -271,16 +273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
271 /// </summary> 273 /// </summary>
272 /// <param name="Script">LSL script</param> 274 /// <param name="Script">LSL script</param>
273 /// <returns>Filename to .dll assembly</returns> 275 /// <returns>Filename to .dll assembly</returns>
274 public object PerformScriptCompile(string Script, string asset, UUID ownerUUID) 276 public void PerformScriptCompile(string Script, string asset, UUID ownerUUID,
277 out string assembly, out Dictionary<KeyValuePair<int,int>, KeyValuePair<int,int>> linemap)
275 { 278 {
276 m_positionMap = null; 279 linemap = null;
277 m_warnings.Clear(); 280 m_warnings.Clear();
278 281
279 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( 282 assembly = Path.Combine(ScriptEnginesPath, Path.Combine(
280 m_scriptEngine.World.RegionInfo.RegionID.ToString(), 283 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
281 FilePrefix + "_compiled_" + asset + ".dll")); 284 FilePrefix + "_compiled_" + asset + ".dll"));
282// string OutFile = Path.Combine(ScriptEnginesPath,
283// FilePrefix + "_compiled_" + asset + ".dll");
284 285
285 if (!Directory.Exists(ScriptEnginesPath)) 286 if (!Directory.Exists(ScriptEnginesPath))
286 { 287 {
@@ -305,51 +306,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
305 } 306 }
306 } 307 }
307 308
308 if (Script == String.Empty) 309 // Don't recompile if we already have it
310 // Performing 3 file exists tests for every script can still be slow
311 if (File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map"))
309 { 312 {
310 if (File.Exists(OutFile)) 313 // If we have already read this linemap file, then it will be in our dictionary.
311 return OutFile; 314 // Don't build another copy of the dictionary (saves memory) and certainly
312 315 // don't keep reading the same file from disk multiple times.
313 throw new Exception("Cannot find script assembly and no script text present"); 316 if (!m_lineMaps.ContainsKey(assembly))
317 m_lineMaps[assembly] = ReadMapFile(assembly + ".map");
318 linemap = m_lineMaps[assembly];
319 return;
314 } 320 }
315 321
316 // Don't recompile if we already have it 322 if (Script == String.Empty)
317 //
318 if (File.Exists(OutFile) && File.Exists(OutFile+".text") && File.Exists(OutFile+".map"))
319 { 323 {
320 ReadMapFile(OutFile+".map"); 324 throw new Exception("Cannot find script assembly and no script text present");
321 return OutFile;
322 } 325 }
323 326
324 enumCompileType l = DefaultCompileLanguage; 327 enumCompileType language = DefaultCompileLanguage;
325 328
326 if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture)) 329 if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture))
327 l = enumCompileType.cs; 330 language = enumCompileType.cs;
328 if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture)) 331 if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture))
329 { 332 {
330 l = enumCompileType.vb; 333 language = enumCompileType.vb;
331 // We need to remove //vb, it won't compile with that 334 // We need to remove //vb, it won't compile with that
332 335
333 Script = Script.Substring(4, Script.Length - 4); 336 Script = Script.Substring(4, Script.Length - 4);
334 } 337 }
335 if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) 338 if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture))
336 l = enumCompileType.lsl; 339 language = enumCompileType.lsl;
337 340
338 if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture)) 341 if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture))
339 l = enumCompileType.js; 342 language = enumCompileType.js;
340 343
341 if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture)) 344 if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture))
342 l = enumCompileType.yp; 345 language = enumCompileType.yp;
343 346
344 if (!AllowedCompilers.ContainsKey(l.ToString())) 347 if (!AllowedCompilers.ContainsKey(language.ToString()))
345 { 348 {
346 // Not allowed to compile to this language! 349 // Not allowed to compile to this language!
347 string errtext = String.Empty; 350 string errtext = String.Empty;
348 errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!"; 351 errtext += "The compiler for language \"" + language.ToString() + "\" is not in list of allowed compilers. Script will not be executed!";
349 throw new Exception(errtext); 352 throw new Exception(errtext);
350 } 353 }
351 354
352 if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)l) == false) { 355 if (m_scriptEngine.World.Permissions.CanCompileScript(ownerUUID, (int)language) == false) {
353 // Not allowed to compile to this language! 356 // Not allowed to compile to this language!
354 string errtext = String.Empty; 357 string errtext = String.Empty;
355 errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!"; 358 errtext += ownerUUID + " is not in list of allowed users for this scripting language. Script will not be executed!";
@@ -358,7 +361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
358 361
359 string compileScript = Script; 362 string compileScript = Script;
360 363
361 if (l == enumCompileType.lsl) 364 if (language == enumCompileType.lsl)
362 { 365 {
363 // Its LSL, convert it to C# 366 // Its LSL, convert it to C#
364 LSL_Converter = (ICodeConverter)new CSCodeGenerator(); 367 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
@@ -370,16 +373,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
370 AddWarning(warning); 373 AddWarning(warning);
371 } 374 }
372 375
373 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; 376 linemap = ((CSCodeGenerator) LSL_Converter).PositionMap;
377 // Write the linemap to a file and save it in our dictionary for next time.
378 m_lineMaps[assembly] = linemap;
379 WriteMapFile(assembly + ".map", linemap);
374 } 380 }
375 381
376 if (l == enumCompileType.yp) 382 if (language == enumCompileType.yp)
377 { 383 {
378 // Its YP, convert it to C# 384 // Its YP, convert it to C#
379 compileScript = YP_Converter.Convert(Script); 385 compileScript = YP_Converter.Convert(Script);
380 } 386 }
381 387
382 switch (l) 388 switch (language)
383 { 389 {
384 case enumCompileType.cs: 390 case enumCompileType.cs:
385 case enumCompileType.lsl: 391 case enumCompileType.lsl:
@@ -396,7 +402,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
396 break; 402 break;
397 } 403 }
398 404
399 return CompileFromDotNetText(compileScript, l, asset); 405 assembly = CompileFromDotNetText(compileScript, language, asset, assembly);
406 return;
400 } 407 }
401 408
402 public string[] GetWarnings() 409 public string[] GetWarnings()
@@ -468,18 +475,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
468 /// </summary> 475 /// </summary>
469 /// <param name="Script">CS script</param> 476 /// <param name="Script">CS script</param>
470 /// <returns>Filename to .dll assembly</returns> 477 /// <returns>Filename to .dll assembly</returns>
471 internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset) 478 internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset, string assembly)
472 { 479 {
473 string ext = "." + lang.ToString(); 480 string ext = "." + lang.ToString();
474 481
475 // Output assembly name 482 // Output assembly name
476 scriptCompileCounter++; 483 scriptCompileCounter++;
477 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
478 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
479 FilePrefix + "_compiled_" + asset + ".dll"));
480 try 484 try
481 { 485 {
482 File.Delete(OutFile); 486 File.Delete(assembly);
483 } 487 }
484 catch (Exception e) // NOTLEGIT - Should be just FileIOException 488 catch (Exception e) // NOTLEGIT - Should be just FileIOException
485 { 489 {
@@ -492,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
492 if (WriteScriptSourceToDebugFile) 496 if (WriteScriptSourceToDebugFile)
493 { 497 {
494 string srcFileName = FilePrefix + "_source_" + 498 string srcFileName = FilePrefix + "_source_" +
495 Path.GetFileNameWithoutExtension(OutFile) + ext; 499 Path.GetFileNameWithoutExtension(assembly) + ext;
496 try 500 try
497 { 501 {
498 File.WriteAllText(Path.Combine(Path.Combine( 502 File.WriteAllText(Path.Combine(Path.Combine(
@@ -528,7 +532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
528 } 532 }
529 533
530 parameters.GenerateExecutable = false; 534 parameters.GenerateExecutable = false;
531 parameters.OutputAssembly = OutFile; 535 parameters.OutputAssembly = assembly;
532 parameters.IncludeDebugInformation = CompileWithDebugInformation; 536 parameters.IncludeDebugInformation = CompileWithDebugInformation;
533 //parameters.WarningLevel = 1; // Should be 4? 537 //parameters.WarningLevel = 1; // Should be 4?
534 parameters.TreatWarningsAsErrors = false; 538 parameters.TreatWarningsAsErrors = false;
@@ -609,7 +613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
609 613
610 if (severity == "Error") 614 if (severity == "Error")
611 { 615 {
612 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column); 616 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]);
613 string text = CompErr.ErrorText; 617 string text = CompErr.ErrorText;
614 618
615 // Use LSL type names 619 // Use LSL type names
@@ -635,14 +639,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
635 // the compile may not be immediately apparent. Wait a 639 // the compile may not be immediately apparent. Wait a
636 // reasonable amount of time before giving up on it. 640 // reasonable amount of time before giving up on it.
637 641
638 if (!File.Exists(OutFile)) 642 if (!File.Exists(assembly))
639 { 643 {
640 for (int i=0; i<20 && !File.Exists(OutFile); i++) 644 for (int i=0; i<20 && !File.Exists(assembly); i++)
641 { 645 {
642 System.Threading.Thread.Sleep(250); 646 System.Threading.Thread.Sleep(250);
643 } 647 }
644 // One final chance... 648 // One final chance...
645 if (!File.Exists(OutFile)) 649 if (!File.Exists(assembly))
646 { 650 {
647 errtext = String.Empty; 651 errtext = String.Empty;
648 errtext += "No compile error. But not able to locate compiled file."; 652 errtext += "No compile error. But not able to locate compiled file.";
@@ -658,7 +662,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
658 // 662 //
659 // Read the binary file into a buffer 663 // Read the binary file into a buffer
660 // 664 //
661 FileInfo fi = new FileInfo(OutFile); 665 FileInfo fi = new FileInfo(assembly);
662 666
663 if (fi == null) 667 if (fi == null)
664 { 668 {
@@ -671,7 +675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
671 675
672 try 676 try
673 { 677 {
674 FileStream fs = File.Open(OutFile, FileMode.Open, FileAccess.Read); 678 FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read);
675 fs.Read(data, 0, data.Length); 679 fs.Read(data, 0, data.Length);
676 fs.Close(); 680 fs.Close();
677 } 681 }
@@ -690,34 +694,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
690 694
691 Byte[] buf = enc.GetBytes(filetext); 695 Byte[] buf = enc.GetBytes(filetext);
692 696
693 FileStream sfs = File.Create(OutFile+".text"); 697 FileStream sfs = File.Create(assembly+".text");
694 sfs.Write(buf, 0, buf.Length); 698 sfs.Write(buf, 0, buf.Length);
695 sfs.Close(); 699 sfs.Close();
696 700
697 string posmap = String.Empty; 701 return assembly;
698 if (m_positionMap != null)
699 {
700 foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in m_positionMap)
701 {
702 KeyValuePair<int, int> k = kvp.Key;
703 KeyValuePair<int, int> v = kvp.Value;
704 posmap += String.Format("{0},{1},{2},{3}\n",
705 k.Key, k.Value, v.Key, v.Value);
706 }
707 }
708
709 buf = enc.GetBytes(posmap);
710
711 FileStream mfs = File.Create(OutFile+".map");
712 mfs.Write(buf, 0, buf.Length);
713 mfs.Close();
714
715 return OutFile;
716 }
717
718 public KeyValuePair<int, int> FindErrorPosition(int line, int col)
719 {
720 return FindErrorPosition(line, col, m_positionMap);
721 } 702 }
722 703
723 private class kvpSorter : IComparer<KeyValuePair<int,int>> 704 private class kvpSorter : IComparer<KeyValuePair<int,int>>
@@ -791,27 +772,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
791 return message; 772 return message;
792 } 773 }
793 774
794 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap() 775
776 private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap)
795 { 777 {
796 if (m_positionMap == null) 778 string mapstring = String.Empty;
797 return null; 779 foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap)
798 780 {
799 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ret = 781 KeyValuePair<int, int> k = kvp.Key;
800 new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>(); 782 KeyValuePair<int, int> v = kvp.Value;
801 783 mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value);
802 foreach (KeyValuePair<int, int> kvp in m_positionMap.Keys) 784 }
803 ret.Add(kvp, m_positionMap[kvp]); 785
804 786 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
805 return ret; 787 Byte[] mapbytes = enc.GetBytes(mapstring);
788 FileStream mfs = File.Create(filename);
789 mfs.Write(mapbytes, 0, mapbytes.Length);
790 mfs.Close();
806 } 791 }
807 792
808 private void ReadMapFile(string filename) 793
794 private static Dictionary<KeyValuePair<int,int>, KeyValuePair<int,int>> ReadMapFile(string filename)
809 { 795 {
796 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
810 try 797 try
811 { 798 {
812 StreamReader r = File.OpenText(filename); 799 StreamReader r = File.OpenText(filename);
813 800 linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
814 m_positionMap = new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>();
815 801
816 string line; 802 string line;
817 while ((line = r.ReadLine()) != null) 803 while ((line = r.ReadLine()) != null)
@@ -825,12 +811,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
825 KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); 811 KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv);
826 KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); 812 KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv);
827 813
828 m_positionMap[k] = v; 814 linemap[k] = v;
829 } 815 }
830 } 816 }
831 catch 817 catch
832 { 818 {
819 linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
833 } 820 }
821 return linemap;
834 } 822 }
835 } 823 }
836} 824}