diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | 314 |
1 files changed, 152 insertions, 162 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 03be2ab..af324bf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs | |||
@@ -58,9 +58,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
58 | { | 58 | { |
59 | lsl = 0, | 59 | lsl = 0, |
60 | cs = 1, | 60 | cs = 1, |
61 | vb = 2, | 61 | vb = 2 |
62 | js = 3, | ||
63 | yp = 4 | ||
64 | } | 62 | } |
65 | 63 | ||
66 | /// <summary> | 64 | /// <summary> |
@@ -72,6 +70,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
72 | private bool CompileWithDebugInformation; | 70 | private bool CompileWithDebugInformation; |
73 | private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); | 71 | private Dictionary<string, bool> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase); |
74 | private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); | 72 | private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); |
73 | private bool m_insertCoopTerminationCalls; | ||
75 | 74 | ||
76 | private string FilePrefix; | 75 | private string FilePrefix; |
77 | private string ScriptEnginesPath = null; | 76 | private string ScriptEnginesPath = null; |
@@ -84,9 +83,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
84 | 83 | ||
85 | private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); | 84 | private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); |
86 | private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); | 85 | private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); |
87 | // private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider(); | ||
88 | private static CSharpCodeProvider YPcodeProvider = new CSharpCodeProvider(); // YP is translated into CSharp | ||
89 | private static YP2CSConverter YP_Converter = new YP2CSConverter(); | ||
90 | 86 | ||
91 | // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files | 87 | // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files |
92 | private static UInt64 scriptCompileCounter = 0; // And a counter | 88 | private static UInt64 scriptCompileCounter = 0; // And a counter |
@@ -95,20 +91,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
95 | private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = | 91 | private Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>> m_lineMaps = |
96 | new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); | 92 | new Dictionary<string, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>>(); |
97 | 93 | ||
94 | public bool in_startup = true; | ||
95 | |||
98 | public Compiler(IScriptEngine scriptEngine) | 96 | public Compiler(IScriptEngine scriptEngine) |
99 | { | 97 | { |
100 | m_scriptEngine = scriptEngine;; | 98 | m_scriptEngine = scriptEngine; |
101 | ScriptEnginesPath = scriptEngine.ScriptEnginePath; | 99 | ScriptEnginesPath = scriptEngine.ScriptEnginePath; |
102 | ReadConfig(); | 100 | ReadConfig(); |
103 | } | 101 | } |
104 | 102 | ||
105 | public bool in_startup = true; | ||
106 | public void ReadConfig() | 103 | public void ReadConfig() |
107 | { | 104 | { |
108 | // Get some config | 105 | // Get some config |
109 | WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); | 106 | WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); |
110 | CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); | 107 | CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); |
111 | bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); | 108 | bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true); |
109 | m_insertCoopTerminationCalls = m_scriptEngine.Config.GetString("ScriptStopStrategy", "abort") == "co-op"; | ||
112 | 110 | ||
113 | // Get file prefix from scriptengine name and make it file system safe: | 111 | // Get file prefix from scriptengine name and make it file system safe: |
114 | FilePrefix = "CommonCompiler"; | 112 | FilePrefix = "CommonCompiler"; |
@@ -120,7 +118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
120 | if (in_startup) | 118 | if (in_startup) |
121 | { | 119 | { |
122 | in_startup = false; | 120 | in_startup = false; |
123 | CreateScriptsDirectory(); | 121 | CheckOrCreateScriptsDirectory(); |
124 | 122 | ||
125 | // First time we start? Delete old files | 123 | // First time we start? Delete old files |
126 | if (DeleteScriptsOnStartup) | 124 | if (DeleteScriptsOnStartup) |
@@ -131,8 +129,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
131 | LanguageMapping.Add(enumCompileType.cs.ToString(), enumCompileType.cs); | 129 | LanguageMapping.Add(enumCompileType.cs.ToString(), enumCompileType.cs); |
132 | LanguageMapping.Add(enumCompileType.vb.ToString(), enumCompileType.vb); | 130 | LanguageMapping.Add(enumCompileType.vb.ToString(), enumCompileType.vb); |
133 | LanguageMapping.Add(enumCompileType.lsl.ToString(), enumCompileType.lsl); | 131 | LanguageMapping.Add(enumCompileType.lsl.ToString(), enumCompileType.lsl); |
134 | LanguageMapping.Add(enumCompileType.js.ToString(), enumCompileType.js); | ||
135 | LanguageMapping.Add(enumCompileType.yp.ToString(), enumCompileType.yp); | ||
136 | 132 | ||
137 | // Allowed compilers | 133 | // Allowed compilers |
138 | string allowComp = m_scriptEngine.Config.GetString("AllowedCompilers", "lsl"); | 134 | string allowComp = m_scriptEngine.Config.GetString("AllowedCompilers", "lsl"); |
@@ -189,13 +185,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
189 | } | 185 | } |
190 | 186 | ||
191 | // We now have an allow-list, a mapping list, and a default language | 187 | // We now have an allow-list, a mapping list, and a default language |
192 | |||
193 | } | 188 | } |
194 | 189 | ||
195 | /// <summary> | 190 | /// <summary> |
196 | /// Create the directory where compiled scripts are stored. | 191 | /// Create the directory where compiled scripts are stored if it does not already exist. |
197 | /// </summary> | 192 | /// </summary> |
198 | private void CreateScriptsDirectory() | 193 | private void CheckOrCreateScriptsDirectory() |
199 | { | 194 | { |
200 | if (!Directory.Exists(ScriptEnginesPath)) | 195 | if (!Directory.Exists(ScriptEnginesPath)) |
201 | { | 196 | { |
@@ -285,15 +280,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
285 | return GetCompilerOutput(assetID.ToString()); | 280 | return GetCompilerOutput(assetID.ToString()); |
286 | } | 281 | } |
287 | 282 | ||
288 | /// <summary> | 283 | public void PerformScriptCompile( |
289 | /// Converts script from LSL to CS and calls CompileFromCSText | 284 | string source, string asset, UUID ownerUUID, |
290 | /// </summary> | ||
291 | /// <param name="Script">LSL script</param> | ||
292 | /// <returns>Filename to .dll assembly</returns> | ||
293 | public void PerformScriptCompile(string Script, string asset, UUID ownerUUID, | ||
294 | out string assembly, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) | 285 | out string assembly, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) |
295 | { | 286 | { |
296 | // m_log.DebugFormat("[Compiler]: Compiling script\n{0}", Script); | 287 | PerformScriptCompile(source, asset, ownerUUID, false, out assembly, out linemap); |
288 | } | ||
289 | |||
290 | public void PerformScriptCompile( | ||
291 | string source, string asset, UUID ownerUUID, bool alwaysRecompile, | ||
292 | out string assembly, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) | ||
293 | { | ||
294 | // m_log.DebugFormat("[Compiler]: Checking script for asset {0} in {1}\n{2}", asset, m_scriptEngine.World.Name, source); | ||
297 | 295 | ||
298 | IScriptModuleComms comms = m_scriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); | 296 | IScriptModuleComms comms = m_scriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); |
299 | 297 | ||
@@ -302,33 +300,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
302 | 300 | ||
303 | assembly = GetCompilerOutput(asset); | 301 | assembly = GetCompilerOutput(asset); |
304 | 302 | ||
305 | if (!Directory.Exists(ScriptEnginesPath)) | 303 | // m_log.DebugFormat("[Compiler]: Retrieved assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); |
306 | { | ||
307 | try | ||
308 | { | ||
309 | Directory.CreateDirectory(ScriptEnginesPath); | ||
310 | } | ||
311 | catch (Exception) | ||
312 | { | ||
313 | } | ||
314 | } | ||
315 | 304 | ||
316 | if (!Directory.Exists(Path.Combine(ScriptEnginesPath, | 305 | CheckOrCreateScriptsDirectory(); |
317 | m_scriptEngine.World.RegionInfo.RegionID.ToString()))) | ||
318 | { | ||
319 | try | ||
320 | { | ||
321 | Directory.CreateDirectory(ScriptEnginesPath); | ||
322 | } | ||
323 | catch (Exception) | ||
324 | { | ||
325 | } | ||
326 | } | ||
327 | 306 | ||
328 | // Don't recompile if we already have it | 307 | // Don't recompile if we're not forced to and we already have it |
329 | // Performing 3 file exists tests for every script can still be slow | 308 | // Performing 3 file exists tests for every script can still be slow |
330 | if (File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map")) | 309 | if (!alwaysRecompile && File.Exists(assembly) && File.Exists(assembly + ".text") && File.Exists(assembly + ".map")) |
331 | { | 310 | { |
311 | // m_log.DebugFormat("[Compiler]: Found existing assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); | ||
312 | |||
332 | // If we have already read this linemap file, then it will be in our dictionary. | 313 | // If we have already read this linemap file, then it will be in our dictionary. |
333 | // Don't build another copy of the dictionary (saves memory) and certainly | 314 | // Don't build another copy of the dictionary (saves memory) and certainly |
334 | // don't keep reading the same file from disk multiple times. | 315 | // don't keep reading the same file from disk multiple times. |
@@ -338,31 +319,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
338 | return; | 319 | return; |
339 | } | 320 | } |
340 | 321 | ||
341 | if (Script == String.Empty) | 322 | // m_log.DebugFormat("[Compiler]: Compiling assembly {0} for asset {1} in {2}", assembly, asset, m_scriptEngine.World.Name); |
342 | { | 323 | |
324 | if (source == String.Empty) | ||
343 | throw new Exception("Cannot find script assembly and no script text present"); | 325 | throw new Exception("Cannot find script assembly and no script text present"); |
344 | } | ||
345 | 326 | ||
346 | enumCompileType language = DefaultCompileLanguage; | 327 | enumCompileType language = DefaultCompileLanguage; |
347 | 328 | ||
348 | if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture)) | 329 | if (source.StartsWith("//c#", true, CultureInfo.InvariantCulture)) |
349 | language = enumCompileType.cs; | 330 | language = enumCompileType.cs; |
350 | if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture)) | 331 | if (source.StartsWith("//vb", true, CultureInfo.InvariantCulture)) |
351 | { | 332 | { |
352 | language = enumCompileType.vb; | 333 | language = enumCompileType.vb; |
353 | // We need to remove //vb, it won't compile with that | 334 | // We need to remove //vb, it won't compile with that |
354 | 335 | ||
355 | Script = Script.Substring(4, Script.Length - 4); | 336 | source = source.Substring(4, source.Length - 4); |
356 | } | 337 | } |
357 | if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) | 338 | if (source.StartsWith("//lsl", true, CultureInfo.InvariantCulture)) |
358 | language = enumCompileType.lsl; | 339 | language = enumCompileType.lsl; |
359 | 340 | ||
360 | if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture)) | ||
361 | language = enumCompileType.js; | ||
362 | |||
363 | if (Script.StartsWith("//yp", true, CultureInfo.InvariantCulture)) | ||
364 | language = enumCompileType.yp; | ||
365 | |||
366 | // m_log.DebugFormat("[Compiler]: Compile language is {0}", language); | 341 | // m_log.DebugFormat("[Compiler]: Compile language is {0}", language); |
367 | 342 | ||
368 | if (!AllowedCompilers.ContainsKey(language.ToString())) | 343 | if (!AllowedCompilers.ContainsKey(language.ToString())) |
@@ -381,13 +356,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
381 | throw new Exception(errtext); | 356 | throw new Exception(errtext); |
382 | } | 357 | } |
383 | 358 | ||
384 | string compileScript = Script; | 359 | string compileScript = source; |
385 | 360 | ||
386 | if (language == enumCompileType.lsl) | 361 | if (language == enumCompileType.lsl) |
387 | { | 362 | { |
388 | // Its LSL, convert it to C# | 363 | // Its LSL, convert it to C# |
389 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); | 364 | LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms, m_insertCoopTerminationCalls); |
390 | compileScript = LSL_Converter.Convert(Script); | 365 | compileScript = LSL_Converter.Convert(source); |
391 | 366 | ||
392 | // copy converter warnings into our warnings. | 367 | // copy converter warnings into our warnings. |
393 | foreach (string warning in LSL_Converter.GetWarnings()) | 368 | foreach (string warning in LSL_Converter.GetWarnings()) |
@@ -401,26 +376,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
401 | WriteMapFile(assembly + ".map", linemap); | 376 | WriteMapFile(assembly + ".map", linemap); |
402 | } | 377 | } |
403 | 378 | ||
404 | if (language == enumCompileType.yp) | ||
405 | { | ||
406 | // Its YP, convert it to C# | ||
407 | compileScript = YP_Converter.Convert(Script); | ||
408 | } | ||
409 | |||
410 | switch (language) | 379 | switch (language) |
411 | { | 380 | { |
412 | case enumCompileType.cs: | 381 | case enumCompileType.cs: |
413 | case enumCompileType.lsl: | 382 | case enumCompileType.lsl: |
414 | compileScript = CreateCSCompilerScript(compileScript); | 383 | compileScript = CreateCSCompilerScript( |
384 | compileScript, | ||
385 | m_scriptEngine.ScriptClassName, | ||
386 | m_scriptEngine.ScriptBaseClassName, | ||
387 | m_scriptEngine.ScriptBaseClassParameters); | ||
415 | break; | 388 | break; |
416 | case enumCompileType.vb: | 389 | case enumCompileType.vb: |
417 | compileScript = CreateVBCompilerScript(compileScript); | 390 | compileScript = CreateVBCompilerScript( |
418 | break; | 391 | compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); |
419 | // case enumCompileType.js: | ||
420 | // compileScript = CreateJSCompilerScript(compileScript); | ||
421 | // break; | ||
422 | case enumCompileType.yp: | ||
423 | compileScript = CreateYPCompilerScript(compileScript); | ||
424 | break; | 392 | break; |
425 | } | 393 | } |
426 | 394 | ||
@@ -451,43 +419,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
451 | // return compileScript; | 419 | // return compileScript; |
452 | // } | 420 | // } |
453 | 421 | ||
454 | private static string CreateCSCompilerScript(string compileScript) | 422 | public static string CreateCSCompilerScript( |
423 | string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) | ||
455 | { | 424 | { |
456 | compileScript = String.Empty + | 425 | compileScript = string.Format( |
457 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + | 426 | @"using OpenSim.Region.ScriptEngine.Shared; |
458 | String.Empty + "namespace SecondLife { " + | 427 | using System.Collections.Generic; |
459 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | 428 | |
460 | @"public Script() { } " + | 429 | namespace SecondLife |
461 | compileScript + | 430 | {{ |
462 | "} }\r\n"; | 431 | public class {0} : {1} |
463 | return compileScript; | 432 | {{ |
464 | } | 433 | public {0}({2}) : base({3}) {{}} |
434 | {4} | ||
435 | }} | ||
436 | }}", | ||
437 | className, | ||
438 | baseClassName, | ||
439 | constructorParameters != null | ||
440 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.ToString())) | ||
441 | : "", | ||
442 | constructorParameters != null | ||
443 | ? string.Join(", ", Array.ConvertAll<ParameterInfo, string>(constructorParameters, pi => pi.Name)) | ||
444 | : "", | ||
445 | compileScript); | ||
465 | 446 | ||
466 | private static string CreateYPCompilerScript(string compileScript) | ||
467 | { | ||
468 | compileScript = String.Empty + | ||
469 | "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + | ||
470 | "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + | ||
471 | String.Empty + "namespace SecondLife { " + | ||
472 | String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + | ||
473 | //@"public Script() { } " + | ||
474 | @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + | ||
475 | @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + | ||
476 | |||
477 | compileScript + | ||
478 | "} }\r\n"; | ||
479 | return compileScript; | 447 | return compileScript; |
480 | } | 448 | } |
481 | 449 | ||
482 | private static string CreateVBCompilerScript(string compileScript) | 450 | public static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) |
483 | { | 451 | { |
484 | compileScript = String.Empty + | 452 | compileScript = String.Empty + |
485 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + | 453 | "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + |
486 | String.Empty + "NameSpace SecondLife:" + | 454 | String.Empty + "NameSpace SecondLife:" + |
487 | String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass: " + | 455 | String.Empty + "Public Class " + className + ": Inherits " + baseClassName + |
488 | "\r\nPublic Sub New()\r\nEnd Sub: " + | 456 | "\r\nPublic Sub New()\r\nEnd Sub: " + |
489 | compileScript + | 457 | compileScript + |
490 | ":End Class :End Namespace\r\n"; | 458 | ":End Class :End Namespace\r\n"; |
459 | |||
491 | return compileScript; | 460 | return compileScript; |
492 | } | 461 | } |
493 | 462 | ||
@@ -506,7 +475,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
506 | scriptCompileCounter++; | 475 | scriptCompileCounter++; |
507 | try | 476 | try |
508 | { | 477 | { |
509 | File.Delete(assembly); | 478 | if (File.Exists(assembly)) |
479 | { | ||
480 | File.SetAttributes(assembly, FileAttributes.Normal); | ||
481 | File.Delete(assembly); | ||
482 | } | ||
510 | } | 483 | } |
511 | catch (Exception e) // NOTLEGIT - Should be just FileIOException | 484 | catch (Exception e) // NOTLEGIT - Should be just FileIOException |
512 | { | 485 | { |
@@ -549,11 +522,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
549 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 522 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, |
550 | "OpenMetaverseTypes.dll")); | 523 | "OpenMetaverseTypes.dll")); |
551 | 524 | ||
552 | if (lang == enumCompileType.yp) | 525 | if (m_scriptEngine.ScriptReferencedAssemblies != null) |
553 | { | 526 | Array.ForEach<string>( |
554 | parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, | 527 | m_scriptEngine.ScriptReferencedAssemblies, |
555 | "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); | 528 | a => parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, a))); |
556 | } | ||
557 | 529 | ||
558 | parameters.GenerateExecutable = false; | 530 | parameters.GenerateExecutable = false; |
559 | parameters.OutputAssembly = assembly; | 531 | parameters.OutputAssembly = assembly; |
@@ -579,6 +551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
579 | results = CScodeProvider.CompileAssemblyFromSource( | 551 | results = CScodeProvider.CompileAssemblyFromSource( |
580 | parameters, Script); | 552 | parameters, Script); |
581 | } | 553 | } |
554 | |||
582 | // Deal with an occasional segv in the compiler. | 555 | // Deal with an occasional segv in the compiler. |
583 | // Rarely, if ever, occurs twice in succession. | 556 | // Rarely, if ever, occurs twice in succession. |
584 | // Line # == 0 and no file name are indications that | 557 | // Line # == 0 and no file name are indications that |
@@ -586,7 +559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
586 | // error log. | 559 | // error log. |
587 | if (results.Errors.Count > 0) | 560 | if (results.Errors.Count > 0) |
588 | { | 561 | { |
589 | if (!retried && (results.Errors[0].FileName == null || results.Errors[0].FileName == String.Empty) && | 562 | if (!retried && string.IsNullOrEmpty(results.Errors[0].FileName) && |
590 | results.Errors[0].Line == 0) | 563 | results.Errors[0].Line == 0) |
591 | { | 564 | { |
592 | // System.Console.WriteLine("retrying failed compilation"); | 565 | // System.Console.WriteLine("retrying failed compilation"); |
@@ -603,41 +576,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
603 | } | 576 | } |
604 | } while (!complete); | 577 | } while (!complete); |
605 | break; | 578 | break; |
606 | // case enumCompileType.js: | ||
607 | // results = JScodeProvider.CompileAssemblyFromSource( | ||
608 | // parameters, Script); | ||
609 | // break; | ||
610 | case enumCompileType.yp: | ||
611 | results = YPcodeProvider.CompileAssemblyFromSource( | ||
612 | parameters, Script); | ||
613 | break; | ||
614 | default: | 579 | default: |
615 | throw new Exception("Compiler is not able to recongnize " + | 580 | throw new Exception("Compiler is not able to recongnize " + |
616 | "language type \"" + lang.ToString() + "\""); | 581 | "language type \"" + lang.ToString() + "\""); |
617 | } | 582 | } |
618 | 583 | ||
619 | // Check result | 584 | // foreach (Type type in results.CompiledAssembly.GetTypes()) |
620 | // Go through errors | 585 | // { |
586 | // foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) | ||
587 | // { | ||
588 | // m_log.DebugFormat("[COMPILER]: {0}.{1}", type.FullName, method.Name); | ||
589 | // } | ||
590 | // } | ||
621 | 591 | ||
622 | // | 592 | // |
623 | // WARNINGS AND ERRORS | 593 | // WARNINGS AND ERRORS |
624 | // | 594 | // |
625 | bool hadErrors = false; | 595 | bool hadErrors = false; |
626 | string errtext = String.Empty; | 596 | string errtext = String.Empty; |
627 | |||
628 | if (results.Errors.Count > 0) | 597 | if (results.Errors.Count > 0) |
629 | { | 598 | { |
630 | foreach (CompilerError CompErr in results.Errors) | 599 | foreach (CompilerError CompErr in results.Errors) |
631 | { | 600 | { |
632 | string severity = CompErr.IsWarning ? "Warning" : "Error"; | 601 | string severity = CompErr.IsWarning ? "Warning" : "Error"; |
633 | 602 | ||
634 | KeyValuePair<int, int> lslPos; | 603 | KeyValuePair<int, int> errorPos; |
635 | 604 | ||
636 | // Show 5 errors max, but check entire list for errors | 605 | // Show 5 errors max, but check entire list for errors |
637 | 606 | ||
638 | if (severity == "Error") | 607 | if (severity == "Error") |
639 | { | 608 | { |
640 | lslPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); | 609 | // C# scripts will not have a linemap since theres no line translation involved. |
610 | if (!m_lineMaps.ContainsKey(assembly)) | ||
611 | errorPos = new KeyValuePair<int, int>(CompErr.Line, CompErr.Column); | ||
612 | else | ||
613 | errorPos = FindErrorPosition(CompErr.Line, CompErr.Column, m_lineMaps[assembly]); | ||
614 | |||
641 | string text = CompErr.ErrorText; | 615 | string text = CompErr.ErrorText; |
642 | 616 | ||
643 | // Use LSL type names | 617 | // Use LSL type names |
@@ -647,7 +621,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
647 | // The Second Life viewer's script editor begins | 621 | // The Second Life viewer's script editor begins |
648 | // countingn lines and columns at 0, so we subtract 1. | 622 | // countingn lines and columns at 0, so we subtract 1. |
649 | errtext += String.Format("({0},{1}): {4} {2}: {3}\n", | 623 | errtext += String.Format("({0},{1}): {4} {2}: {3}\n", |
650 | lslPos.Key - 1, lslPos.Value - 1, | 624 | errorPos.Key - 1, errorPos.Value - 1, |
651 | CompErr.ErrorNumber, text, severity); | 625 | CompErr.ErrorNumber, text, severity); |
652 | hadErrors = true; | 626 | hadErrors = true; |
653 | } | 627 | } |
@@ -699,9 +673,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
699 | 673 | ||
700 | try | 674 | try |
701 | { | 675 | { |
702 | FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); | 676 | using (FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read)) |
703 | fs.Read(data, 0, data.Length); | 677 | fs.Read(data, 0, data.Length); |
704 | fs.Close(); | ||
705 | } | 678 | } |
706 | catch (Exception) | 679 | catch (Exception) |
707 | { | 680 | { |
@@ -716,19 +689,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
716 | 689 | ||
717 | Byte[] buf = Encoding.ASCII.GetBytes(filetext); | 690 | Byte[] buf = Encoding.ASCII.GetBytes(filetext); |
718 | 691 | ||
719 | FileStream sfs = File.Create(assembly + ".text"); | 692 | using (FileStream sfs = File.Create(assembly + ".text")) |
720 | sfs.Write(buf, 0, buf.Length); | 693 | sfs.Write(buf, 0, buf.Length); |
721 | sfs.Close(); | ||
722 | 694 | ||
723 | return assembly; | 695 | return assembly; |
724 | } | 696 | } |
725 | 697 | ||
726 | private class kvpSorter : IComparer<KeyValuePair<int, int>> | 698 | private class kvpSorter : IComparer<KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>>> |
727 | { | 699 | { |
728 | public int Compare(KeyValuePair<int, int> a, | 700 | public int Compare(KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> a, |
729 | KeyValuePair<int, int> b) | 701 | KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> b) |
730 | { | 702 | { |
731 | return a.Key.CompareTo(b.Key); | 703 | int kc = a.Key.Key.CompareTo(b.Key.Key); |
704 | return (kc != 0) ? kc : a.Key.Value.CompareTo(b.Key.Value); | ||
732 | } | 705 | } |
733 | } | 706 | } |
734 | 707 | ||
@@ -745,30 +718,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
745 | out ret)) | 718 | out ret)) |
746 | return ret; | 719 | return ret; |
747 | 720 | ||
748 | List<KeyValuePair<int, int>> sorted = | 721 | var sorted = new List<KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>>>(positionMap); |
749 | new List<KeyValuePair<int, int>>(positionMap.Keys); | ||
750 | 722 | ||
751 | sorted.Sort(new kvpSorter()); | 723 | sorted.Sort(new kvpSorter()); |
752 | 724 | ||
753 | int l = 1; | 725 | int l = 1; |
754 | int c = 1; | 726 | int c = 1; |
727 | int pl = 1; | ||
755 | 728 | ||
756 | foreach (KeyValuePair<int, int> cspos in sorted) | 729 | foreach (KeyValuePair<KeyValuePair<int, int>, KeyValuePair<int, int>> posmap in sorted) |
757 | { | 730 | { |
758 | if (cspos.Key >= line) | 731 | //m_log.DebugFormat("[Compiler]: Scanning line map {0},{1} --> {2},{3}", posmap.Key.Key, posmap.Key.Value, posmap.Value.Key, posmap.Value.Value); |
732 | int nl = posmap.Value.Key + line - posmap.Key.Key; // New, translated LSL line and column. | ||
733 | int nc = posmap.Value.Value + col - posmap.Key.Value; | ||
734 | // Keep going until we find the first point passed line,col. | ||
735 | if (posmap.Key.Key > line) | ||
759 | { | 736 | { |
760 | if (cspos.Key > line) | 737 | //m_log.DebugFormat("[Compiler]: Line is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); |
761 | return new KeyValuePair<int, int>(l, c); | 738 | if (pl < line) |
762 | if (cspos.Value > col) | 739 | { |
763 | return new KeyValuePair<int, int>(l, c); | 740 | //m_log.DebugFormat("[Compiler]: Previous line ({0}) is less than requested line ({1}), setting column to 1.", pl, line); |
764 | c = cspos.Value; | 741 | c = 1; |
765 | if (c == 0) | 742 | } |
766 | c++; | 743 | break; |
767 | } | 744 | } |
768 | else | 745 | if (posmap.Key.Key == line && posmap.Key.Value > col) |
769 | { | 746 | { |
770 | l = cspos.Key; | 747 | // Never move l,c backwards. |
748 | if (nl > l || (nl == l && nc > c)) | ||
749 | { | ||
750 | //m_log.DebugFormat("[Compiler]: Using offset relative to this: {0} + {1} - {2}, {3} + {4} - {5} = {6}, {7}", | ||
751 | // posmap.Value.Key, line, posmap.Key.Key, posmap.Value.Value, col, posmap.Key.Value, nl, nc); | ||
752 | l = nl; | ||
753 | c = nc; | ||
754 | } | ||
755 | //m_log.DebugFormat("[Compiler]: Column is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); | ||
756 | break; | ||
771 | } | 757 | } |
758 | pl = posmap.Key.Key; | ||
759 | l = posmap.Value.Key; | ||
760 | c = posmap.Value.Value; | ||
772 | } | 761 | } |
773 | return new KeyValuePair<int, int>(l, c); | 762 | return new KeyValuePair<int, int>(l, c); |
774 | } | 763 | } |
@@ -794,7 +783,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
794 | return message; | 783 | return message; |
795 | } | 784 | } |
796 | 785 | ||
797 | |||
798 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) | 786 | private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap) |
799 | { | 787 | { |
800 | string mapstring = String.Empty; | 788 | string mapstring = String.Empty; |
@@ -806,40 +794,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools | |||
806 | } | 794 | } |
807 | 795 | ||
808 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); | 796 | Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring); |
809 | FileStream mfs = File.Create(filename); | ||
810 | mfs.Write(mapbytes, 0, mapbytes.Length); | ||
811 | mfs.Close(); | ||
812 | } | ||
813 | 797 | ||
798 | using (FileStream mfs = File.Create(filename)) | ||
799 | mfs.Write(mapbytes, 0, mapbytes.Length); | ||
800 | } | ||
814 | 801 | ||
815 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename) | 802 | private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename) |
816 | { | 803 | { |
817 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; | 804 | Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; |
818 | try | 805 | try |
819 | { | 806 | { |
820 | StreamReader r = File.OpenText(filename); | 807 | using (StreamReader r = File.OpenText(filename)) |
821 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); | ||
822 | |||
823 | string line; | ||
824 | while ((line = r.ReadLine()) != null) | ||
825 | { | 808 | { |
826 | String[] parts = line.Split(new Char[] { ',' }); | 809 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); |
827 | int kk = System.Convert.ToInt32(parts[0]); | ||
828 | int kv = System.Convert.ToInt32(parts[1]); | ||
829 | int vk = System.Convert.ToInt32(parts[2]); | ||
830 | int vv = System.Convert.ToInt32(parts[3]); | ||
831 | 810 | ||
832 | KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); | 811 | string line; |
833 | KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); | 812 | while ((line = r.ReadLine()) != null) |
813 | { | ||
814 | String[] parts = line.Split(new Char[] { ',' }); | ||
815 | int kk = System.Convert.ToInt32(parts[0]); | ||
816 | int kv = System.Convert.ToInt32(parts[1]); | ||
817 | int vk = System.Convert.ToInt32(parts[2]); | ||
818 | int vv = System.Convert.ToInt32(parts[3]); | ||
819 | |||
820 | KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv); | ||
821 | KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv); | ||
834 | 822 | ||
835 | linemap[k] = v; | 823 | linemap[k] = v; |
824 | } | ||
836 | } | 825 | } |
837 | } | 826 | } |
838 | catch | 827 | catch |
839 | { | 828 | { |
840 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); | 829 | linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>(); |
841 | } | 830 | } |
831 | |||
842 | return linemap; | 832 | return linemap; |
843 | } | 833 | } |
844 | } | 834 | } |
845 | } | 835 | } \ No newline at end of file |