diff options
author | onefang | 2019-09-11 16:36:50 +1000 |
---|---|---|
committer | onefang | 2019-09-11 16:36:50 +1000 |
commit | 50cd1ffd32f69228e566f2b0b89f86ea0d9fe489 (patch) | |
tree | 52f2ab0c04f1a5d7d6ac5dc872981b4b156447e7 /OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |
parent | Renamed branch to SledjChisl. (diff) | |
parent | Bump to release flavour, build 0. (diff) | |
download | opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.zip opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.gz opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.bz2 opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.xz |
Merge branch 'SledjChisl'
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | 230 |
1 files changed, 124 insertions, 106 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index af324bf..89211a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |||
@@ -79,12 +79,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
79 | 79 | ||
80 | private List<string> m_warnings = new List<string>(); | 80 | private List<string> m_warnings = new List<string>(); |
81 | 81 | ||
82 | // private object m_syncy = new object(); | ||
83 | |||
84 | private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | ||
85 | private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); | ||
86 | |||
87 | // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files | ||
88 | private static UInt64 scriptCompileCounter = 0; // And a counter | 82 | private static UInt64 scriptCompileCounter = 0; // And a counter |
89 | 83 | ||
90 | public IScriptEngine m_scriptEngine; | 84 | public IScriptEngine m_scriptEngine; |
@@ -119,7 +113,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
119 | { | 113 | { |
120 | in_startup = false; | 114 | in_startup = false; |
121 | CheckOrCreateScriptsDirectory(); | 115 | CheckOrCreateScriptsDirectory(); |
122 | 116 | ||
123 | // First time we start? Delete old files | 117 | // First time we start? Delete old files |
124 | if (DeleteScriptsOnStartup) | 118 | if (DeleteScriptsOnStartup) |
125 | DeleteOldFiles(); | 119 | DeleteOldFiles(); |
@@ -251,23 +245,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
251 | } | 245 | } |
252 | } | 246 | } |
253 | 247 | ||
254 | ////private ICodeCompiler icc = codeProvider.CreateCompiler(); | ||
255 | //public string CompileFromFile(string LSOFileName) | ||
256 | //{ | ||
257 | // switch (Path.GetExtension(LSOFileName).ToLower()) | ||
258 | // { | ||
259 | // case ".txt": | ||
260 | // case ".lsl": | ||
261 | // Common.ScriptEngineBase.Shared.SendToDebug("Source code is LSL, converting to CS"); | ||
262 | // return CompileFromLSLText(File.ReadAllText(LSOFileName)); | ||
263 | // case ".cs": | ||
264 | // Common.ScriptEngineBase.Shared.SendToDebug("Source code is CS"); | ||
265 | // return CompileFromCSText(File.ReadAllText(LSOFileName)); | ||
266 | // default: | ||
267 | // throw new Exception("Unknown script type."); | ||
268 | // } | ||
269 | //} | ||
270 | |||
271 | public string GetCompilerOutput(string assetID) | 248 | public string GetCompilerOutput(string assetID) |
272 | { | 249 | { |
273 | return Path.Combine(ScriptEnginesPath, Path.Combine( | 250 | return Path.Combine(ScriptEnginesPath, Path.Combine( |
@@ -310,9 +287,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
310 | { | 287 | { |
311 | // m_log.DebugFormat("[Compiler]: Found existing assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); | 288 | // m_log.DebugFormat("[Compiler]: Found existing assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); |
312 | 289 | ||
313 | // If we have already read this linemap file, then it will be in our dictionary. | 290 | // If we have already read this linemap file, then it will be in our dictionary. |
314 | // Don't build another copy of the dictionary (saves memory) and certainly | 291 | // Don't build another copy of the dictionary (saves memory) and certainly |
315 | // don't keep reading the same file from disk multiple times. | 292 | // don't keep reading the same file from disk multiple times. |
316 | if (!m_lineMaps.ContainsKey(assembly)) | 293 | if (!m_lineMaps.ContainsKey(assembly)) |
317 | m_lineMaps[assembly] = ReadMapFile(assembly + ".map"); | 294 | m_lineMaps[assembly] = ReadMapFile(assembly + ".map"); |
318 | linemap = m_lineMaps[assembly]; | 295 | linemap = m_lineMaps[assembly]; |
@@ -356,14 +333,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
356 | throw new Exception(errtext); | 333 | throw new Exception(errtext); |
357 | } | 334 | } |
358 | 335 | ||
359 | string compileScript = source; | 336 | string compileScript = string.Empty; |
360 | 337 | ||
361 | if (language == enumCompileType.lsl) | 338 | if (language == enumCompileType.lsl) |
362 | { | 339 | { |
363 | // Its LSL, convert it to C# | 340 | // Its LSL, convert it to C# |
364 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); | ||
365 | compileScript = LSL_Converter.Convert(source); | ||
366 | 341 | ||
342 | StringBuilder sb = new StringBuilder(16394); | ||
343 | |||
344 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); | ||
345 | AddCSScriptHeader( | ||
346 | m_scriptEngine.ScriptClassName, | ||
347 | m_scriptEngine.ScriptBaseClassName, | ||
348 | m_scriptEngine.ScriptBaseClassParameters, | ||
349 | sb); | ||
350 | |||
351 | LSL_Converter.Convert(source,sb); | ||
352 | AddCSScriptTail(sb); | ||
353 | compileScript = sb.ToString(); | ||
367 | // copy converter warnings into our warnings. | 354 | // copy converter warnings into our warnings. |
368 | foreach (string warning in LSL_Converter.GetWarnings()) | 355 | foreach (string warning in LSL_Converter.GetWarnings()) |
369 | { | 356 | { |
@@ -371,25 +358,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
371 | } | 358 | } |
372 | 359 | ||
373 | linemap = ((CSCodeGenerator)LSL_Converter).PositionMap; | 360 | linemap = ((CSCodeGenerator)LSL_Converter).PositionMap; |
374 | // Write the linemap to a file and save it in our dictionary for next time. | 361 | // Write the linemap to a file and save it in our dictionary for next time. |
375 | m_lineMaps[assembly] = linemap; | 362 | m_lineMaps[assembly] = linemap; |
376 | WriteMapFile(assembly + ".map", linemap); | 363 | WriteMapFile(assembly + ".map", linemap); |
364 | LSL_Converter.Clear(); | ||
377 | } | 365 | } |
378 | 366 | else | |
379 | switch (language) | ||
380 | { | 367 | { |
381 | case enumCompileType.cs: | 368 | switch (language) |
382 | case enumCompileType.lsl: | 369 | { |
383 | compileScript = CreateCSCompilerScript( | 370 | case enumCompileType.cs: |
384 | compileScript, | 371 | compileScript = CreateCSCompilerScript( |
385 | m_scriptEngine.ScriptClassName, | 372 | source, |
386 | m_scriptEngine.ScriptBaseClassName, | 373 | m_scriptEngine.ScriptClassName, |
387 | m_scriptEngine.ScriptBaseClassParameters); | 374 | m_scriptEngine.ScriptBaseClassName, |
388 | break; | 375 | m_scriptEngine.ScriptBaseClassParameters); |
389 | case enumCompileType.vb: | 376 | break; |
390 | compileScript = CreateVBCompilerScript( | 377 | case enumCompileType.vb: |
391 | compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); | 378 | compileScript = CreateVBCompilerScript( |
392 | break; | 379 | source, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); |
380 | break; | ||
381 | } | ||
393 | } | 382 | } |
394 | 383 | ||
395 | assembly = CompileFromDotNetText(compileScript, language, asset, assembly); | 384 | assembly = CompileFromDotNetText(compileScript, language, asset, assembly); |
@@ -419,29 +408,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
419 | // return compileScript; | 408 | // return compileScript; |
420 | // } | 409 | // } |
421 | 410 | ||
411 | public static void AddCSScriptHeader(string className, string baseClassName, ParameterInfo[] constructorParameters, StringBuilder sb) | ||
412 | { | ||
413 | sb.Append(string.Format( | ||
414 | @"using OpenSim.Region.ScriptEngine.Shared; | ||
415 | using System.Collections.Generic; | ||
416 | |||
417 | namespace SecondLife | ||
418 | {{ | ||
419 | public class {0} : {1} | ||
420 | {{ | ||
421 | public {0}({2}) : base({3}) {{}} | ||
422 | ", | ||
423 | className, | ||
424 | baseClassName, | ||
425 | constructorParameters != null | ||
426 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) | ||
427 | : "", | ||
428 | constructorParameters != null | ||
429 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) | ||
430 | : "" | ||
431 | )); | ||
432 | } | ||
433 | |||
434 | public static void AddCSScriptTail(StringBuilder sb) | ||
435 | { | ||
436 | sb.Append(string.Format(" }}\n}}\n")); | ||
437 | } | ||
438 | |||
422 | public static string CreateCSCompilerScript( | 439 | public static string CreateCSCompilerScript( |
423 | string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) | 440 | string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) |
424 | { | 441 | { |
425 | compileScript = string.Format( | 442 | compileScript = string.Format( |
426 | @"using OpenSim.Region.ScriptEngine.Shared; | 443 | @"using OpenSim.Region.ScriptEngine.Shared; |
427 | using System.Collections.Generic; | 444 | using System.Collections.Generic; |
428 | 445 | ||
429 | namespace SecondLife | 446 | namespace SecondLife |
430 | {{ | 447 | {{ |
431 | public class {0} : {1} | 448 | public class {0} : {1} |
432 | {{ | 449 | {{ |
433 | public {0}({2}) : base({3}) {{}} | 450 | public {0}({2}) : base({3}) {{}} |
434 | {4} | 451 | {4} |
435 | }} | 452 | }} |
436 | }}", | 453 | }}", |
437 | className, | 454 | className, |
438 | baseClassName, | 455 | baseClassName, |
439 | constructorParameters != null | 456 | constructorParameters != null |
440 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) | 457 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) |
441 | : "", | 458 | : "", |
442 | constructorParameters != null | 459 | constructorParameters != null |
443 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) | 460 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) |
444 | : "", | 461 | : "", |
445 | compileScript); | 462 | compileScript); |
446 | 463 | ||
447 | return compileScript; | 464 | return compileScript; |
@@ -468,7 +485,7 @@ namespace SecondLife | |||
468 | internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset, string assembly) | 485 | internal string CompileFromDotNetText(string Script, enumCompileType lang, string asset, string assembly) |
469 | { | 486 | { |
470 | // m_log.DebugFormat("[Compiler]: Compiling to assembly\n{0}", Script); | 487 | // m_log.DebugFormat("[Compiler]: Compiling to assembly\n{0}", Script); |
471 | 488 | ||
472 | string ext = "." + lang.ToString(); | 489 | string ext = "." + lang.ToString(); |
473 | 490 | ||
474 | // Output assembly name | 491 | // Output assembly name |
@@ -511,8 +528,6 @@ namespace SecondLife | |||
511 | // Do actual compile | 528 | // Do actual compile |
512 | CompilerParameters parameters = new CompilerParameters(); | 529 | CompilerParameters parameters = new CompilerParameters(); |
513 | 530 | ||
514 | parameters.IncludeDebugInformation = true; | ||
515 | |||
516 | string rootPath = AppDomain.CurrentDomain.BaseDirectory; | 531 | string rootPath = AppDomain.CurrentDomain.BaseDirectory; |
517 | 532 | ||
518 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 533 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
@@ -524,7 +539,7 @@ namespace SecondLife | |||
524 | 539 | ||
525 | if (m_scriptEngine.ScriptReferencedAssemblies != null) | 540 | if (m_scriptEngine.ScriptReferencedAssemblies != null) |
526 | Array.ForEach<string>( | 541 | Array.ForEach<string>( |
527 | m_scriptEngine.ScriptReferencedAssemblies, | 542 | m_scriptEngine.ScriptReferencedAssemblies, |
528 | a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); | 543 | a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); |
529 | 544 | ||
530 | parameters.GenerateExecutable = false; | 545 | parameters.GenerateExecutable = false; |
@@ -532,62 +547,62 @@ namespace SecondLife | |||
532 | parameters.IncludeDebugInformation = CompileWithDebugInformation; | 547 | parameters.IncludeDebugInformation = CompileWithDebugInformation; |
533 | //parameters.WarningLevel = 1; // Should be 4? | 548 | //parameters.WarningLevel = 1; // Should be 4? |
534 | parameters.TreatWarningsAsErrors = false; | 549 | parameters.TreatWarningsAsErrors = false; |
550 | parameters.GenerateInMemory = false; | ||
551 | |||
552 | // this seems to cause issues on some windows servers | ||
553 | // parameters.TempFiles = new TempFileCollection(Path.Combine(ScriptEnginesPath, | ||
554 | // m_scriptEngine.World.RegionInfo.RegionID.ToString()), CompileWithDebugInformation); | ||
535 | 555 | ||
536 | CompilerResults results; | 556 | CompilerResults results; |
557 | |||
558 | CodeDomProvider provider; | ||
537 | switch (lang) | 559 | switch (lang) |
538 | { | 560 | { |
539 | case enumCompileType.vb: | 561 | case enumCompileType.vb: |
540 | results = VBcodeProvider.CompileAssemblyFromSource( | 562 | provider = CodeDomProvider.CreateProvider("VisualBasic"); |
541 | parameters, Script); | ||
542 | break; | 563 | break; |
543 | case enumCompileType.cs: | 564 | case enumCompileType.cs: |
544 | case enumCompileType.lsl: | 565 | case enumCompileType.lsl: |
545 | bool complete = false; | 566 | provider = CodeDomProvider.CreateProvider("CSharp"); |
546 | bool retried = false; | ||
547 | do | ||
548 | { | ||
549 | lock (CScodeProvider) | ||
550 | { | ||
551 | results = CScodeProvider.CompileAssemblyFromSource( | ||
552 | parameters, Script); | ||
553 | } | ||
554 | |||
555 | // Deal with an occasional segv in the compiler. | ||
556 | // Rarely, if ever, occurs twice in succession. | ||
557 | // Line # == 0 and no file name are indications that | ||
558 | // this is a native stack trace rather than a normal | ||
559 | // error log. | ||
560 | if (results.Errors.Count > 0) | ||
561 | { | ||
562 | if (!retried && string.IsNullOrEmpty(results.Errors[0].FileName) && | ||
563 | results.Errors[0].Line == 0) | ||
564 | { | ||
565 | // System.Console.WriteLine("retrying failed compilation"); | ||
566 | retried = true; | ||
567 | } | ||
568 | else | ||
569 | { | ||
570 | complete = true; | ||
571 | } | ||
572 | } | ||
573 | else | ||
574 | { | ||
575 | complete = true; | ||
576 | } | ||
577 | } while (!complete); | ||
578 | break; | 567 | break; |
579 | default: | 568 | default: |
580 | throw new Exception("Compiler is not able to recongnize " + | 569 | throw new Exception("Compiler is not able to recongnize " + |
581 | "language type \"" + lang.ToString() + "\""); | 570 | "language type \"" + lang.ToString() + "\""); |
582 | } | 571 | } |
583 | 572 | ||
584 | // foreach (Type type in results.CompiledAssembly.GetTypes()) | 573 | if(provider == null) |
585 | // { | 574 | throw new Exception("Compiler failed to load "); |
586 | // foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) | 575 | |
587 | // { | 576 | bool complete = false; |
588 | // m_log.DebugFormat("[COMPILER]: {0}.{1}", type.FullName, method.Name); | 577 | bool retried = false; |
589 | // } | 578 | |
590 | // } | 579 | do |
580 | { | ||
581 | results = provider.CompileAssemblyFromSource( | ||
582 | parameters, Script); | ||
583 | // Deal with an occasional segv in the compiler. | ||
584 | // Rarely, if ever, occurs twice in succession. | ||
585 | // Line # == 0 and no file name are indications that | ||
586 | // this is a native stack trace rather than a normal | ||
587 | // error log. | ||
588 | if (results.Errors.Count > 0) | ||
589 | { | ||
590 | if (!retried && string.IsNullOrEmpty(results.Errors[0].FileName) && | ||
591 | results.Errors[0].Line == 0) | ||
592 | { | ||
593 | // System.Console.WriteLine("retrying failed compilation"); | ||
594 | retried = true; | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | complete = true; | ||
599 | } | ||
600 | } | ||
601 | else | ||
602 | { | ||
603 | complete = true; | ||
604 | } | ||
605 | } while (!complete); | ||
591 | 606 | ||
592 | // | 607 | // |
593 | // WARNINGS AND ERRORS | 608 | // WARNINGS AND ERRORS |
@@ -628,13 +643,15 @@ namespace SecondLife | |||
628 | } | 643 | } |
629 | } | 644 | } |
630 | 645 | ||
646 | provider.Dispose(); | ||
647 | |||
631 | if (hadErrors) | 648 | if (hadErrors) |
632 | { | 649 | { |
633 | throw new Exception(errtext); | 650 | throw new Exception(errtext); |
634 | } | 651 | } |
635 | 652 | ||
636 | // On today's highly asynchronous systems, the result of | 653 | // On today's highly asynchronous systems, the result of |
637 | // the compile may not be immediately apparent. Wait a | 654 | // the compile may not be immediately apparent. Wait a |
638 | // reasonable amount of time before giving up on it. | 655 | // reasonable amount of time before giving up on it. |
639 | 656 | ||
640 | if (!File.Exists(assembly)) | 657 | if (!File.Exists(assembly)) |
@@ -785,15 +802,16 @@ namespace SecondLife | |||
785 | 802 | ||
786 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) | 803 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) |
787 | { | 804 | { |
788 | string mapstring = String.Empty; | 805 | StringBuilder mapbuilder = new StringBuilder(1024); |
806 | |||
789 | foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap) | 807 | foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> kvp in linemap) |
790 | { | 808 | { |
791 | KeyValuePair<int, int> k = kvp.Key; | 809 | KeyValuePair<int, int> k = kvp.Key; |
792 | KeyValuePair<int, int> v = kvp.Value; | 810 | KeyValuePair<int, int> v = kvp.Value; |
793 | mapstring += String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value); | 811 | mapbuilder.Append(String.Format("{0},{1},{2},{3}\n", k.Key, k.Value, v.Key, v.Value)); |
794 | } | 812 | } |
795 | 813 | ||
796 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); | 814 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapbuilder.ToString()); |
797 | 815 | ||
798 | using (FileStream mfs = File.Create(filename)) | 816 | using (FileStream mfs = File.Create(filename)) |
799 | mfs.Write(mapbytes, 0, mapbytes.Length); | 817 | mfs.Write(mapbytes, 0, mapbytes.Length); |