aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie Thielker2008-09-27 05:31:43 +0000
committerMelanie Thielker2008-09-27 05:31:43 +0000
commit85068dae60db02b168a29ffd75e1408e30d279e1 (patch)
tree8389c246a6e9891eb1bf310b85cba19a1668d790
parentMantis #2277 (diff)
downloadopensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.zip
opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.gz
opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.bz2
opensim-SC-85068dae60db02b168a29ffd75e1408e30d279e1.tar.xz
Add friendly error messages to both engines.
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs92
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs19
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs225
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs5
9 files changed, 303 insertions, 109 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs
index 634a12b..4a094e2 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs
@@ -139,6 +139,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
139 public string functionName; 139 public string functionName;
140 public DetectParams[] llDetectParams; 140 public DetectParams[] llDetectParams;
141 public object[] param; 141 public object[] param;
142 public Dictionary<KeyValuePair<int,int>,KeyValuePair<int,int>>
143 LineMap;
142 } 144 }
143 145
144 #endregion 146 #endregion
@@ -349,6 +351,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
349 return false; 351 return false;
350 } 352 }
351 353
354 InstanceData id = m_ScriptEngine.m_ScriptManager.GetScript(
355 localID, itemID);
356
352 // Create a structure and add data 357 // Create a structure and add data
353 QueueItemStruct QIS = new QueueItemStruct(); 358 QueueItemStruct QIS = new QueueItemStruct();
354 QIS.localID = localID; 359 QIS.localID = localID;
@@ -356,6 +361,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
356 QIS.functionName = FunctionName; 361 QIS.functionName = FunctionName;
357 QIS.llDetectParams = qParams; 362 QIS.llDetectParams = qParams;
358 QIS.param = param; 363 QIS.param = param;
364 if (id != null)
365 QIS.LineMap = id.LineMap;
359 366
360 // Add it to queue 367 // Add it to queue
361 eventQueue.Enqueue(QIS); 368 eventQueue.Enqueue(QIS);
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
index 2d60ed5..16dafdc 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueThreadClass.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using System.Text.RegularExpressions; 32using System.Text.RegularExpressions;
32using System.Threading; 33using System.Threading;
@@ -37,6 +38,7 @@ using OpenSim.Framework;
37using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
38using OpenSim.Region.Environment.Scenes.Scripting; 39using OpenSim.Region.Environment.Scenes.Scripting;
39using OpenSim.Region.ScriptEngine.Shared; 40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.CodeTools;
40 42
41namespace OpenSim.Region.ScriptEngine.DotNetEngine 43namespace OpenSim.Region.ScriptEngine.DotNetEngine
42{ 44{
@@ -198,10 +200,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
198 } 200 }
199 catch (Exception e) 201 catch (Exception e)
200 { 202 {
201 if (lastScriptEngine != null)
202 lastScriptEngine.Log.Error("[" + ScriptEngineName +
203 "]: Exception in EventQueueThreadLoop: " +
204 e.ToString());
205 } 203 }
206 } 204 }
207 } 205 }
@@ -290,32 +288,32 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
290 catch (Exception e) 288 catch (Exception e)
291 { 289 {
292 InExecution = false; 290 InExecution = false;
291 string text = FormatException(e, QIS.LineMap);
292
293 // DISPLAY ERROR INWORLD 293 // DISPLAY ERROR INWORLD
294 string text = "Error executing script function \"" +
295 QIS.functionName + "\":\r\n";
296 294
297 if (e.InnerException != null) 295// if (e.InnerException != null)
298 { 296// {
299 // Send inner exception 297// // Send inner exception
300 string line = " (unknown line)"; 298// string line = " (unknown line)";
301 Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled); 299// Regex rx = new Regex(@"SecondLife\.Script\..+[\s:](?<line>\d+)\.?\r?$", RegexOptions.Compiled);
302 if (rx.Match(e.InnerException.ToString()).Success) 300// if (rx.Match(e.InnerException.ToString()).Success)
303 line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")"; 301// line = " (line " + rx.Match(e.InnerException.ToString()).Result("${line}") + ")";
304 text += e.InnerException.Message.ToString() + line; 302// text += e.InnerException.Message.ToString() + line;
305 } 303// }
306 else 304// else
307 { 305// {
308 text += "\r\n"; 306// text += "\r\n";
309 // Send normal 307// // Send normal
310 text += e.Message.ToString(); 308// text += e.Message.ToString();
311 } 309// }
312 if (KillCurrentScript) 310// if (KillCurrentScript)
313 text += "\r\nScript will be deactivated!"; 311// text += "\r\nScript will be deactivated!";
314 312
315 try 313 try
316 { 314 {
317 if (text.Length > 1500) 315 if (text.Length >= 1100)
318 text = text.Substring(0, 1500); 316 text = text.Substring(0, 1099);
319 IScriptHost m_host = 317 IScriptHost m_host =
320 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); 318 m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
321 m_ScriptEngine.World.SimChat( 319 m_ScriptEngine.World.SimChat(
@@ -343,10 +341,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
343 QIS.localID, QIS.itemID); 341 QIS.localID, QIS.itemID);
344 } 342 }
345 } 343 }
346
347 // Pass it on so it's displayed on the console
348 // and in the logs (mikem 2008.06.02).
349 throw e.InnerException;
350 } 344 }
351 finally 345 finally
352 { 346 {
@@ -358,5 +352,45 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
358 } 352 }
359 } 353 }
360 } 354 }
355
356 string FormatException(Exception e, Dictionary<KeyValuePair<int,int>,
357 KeyValuePair<int,int>> LineMap)
358 {
359 string message = "Runtime error:\n" + e.InnerException.StackTrace;
360 string[] lines = message.Split(new char[] {'\n'});
361
362 foreach (string line in lines)
363 {
364 if (line.Contains("SecondLife.Script"))
365 {
366 int idx = line.IndexOf(':');
367 if (idx != -1)
368 {
369 string val = line.Substring(idx+1);
370 int lineNum = 0;
371 if (int.TryParse(val, out lineNum))
372 {
373 KeyValuePair<int, int> pos =
374 Compiler.FindErrorPosition(
375 lineNum, 0, LineMap);
376
377 int scriptLine = pos.Key;
378 int col = pos.Value;
379 if (scriptLine == 0)
380 scriptLine++;
381 if (col == 0)
382 col++;
383 message = string.Format("Runtime error:\n" +
384 "Line ({0}): {1}", scriptLine - 1,
385 e.InnerException.Message);
386
387 return message;
388 }
389 }
390 }
391 }
392
393 return message;
394 }
361 } 395 }
362} 396}
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index 8329805..1c1dcf3 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -53,6 +53,8 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
53 public int StartParam; 53 public int StartParam;
54 public AppDomain AppDomain; 54 public AppDomain AppDomain;
55 public Dictionary<string, IScriptApi> Apis; 55 public Dictionary<string, IScriptApi> Apis;
56 public Dictionary<KeyValuePair<int,int>, KeyValuePair<int,int>>
57 LineMap;
56 } 58 }
57 59
58 public class ScriptManager 60 public class ScriptManager
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
159 m_scriptEngine.m_AppDomainManager.LoadScript( 161 m_scriptEngine.m_AppDomainManager.LoadScript(
160 CompiledScriptFile, out id.AppDomain); 162 CompiledScriptFile, out id.AppDomain);
161 163
164 id.LineMap = LSLCompiler.LineMap();
162 id.Script = CompiledScript; 165 id.Script = CompiledScript;
163 id.Source = Script; 166 id.Source = Script;
164 id.StartParam = startParam; 167 id.StartParam = startParam;
@@ -212,7 +215,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
212 try 215 try
213 { 216 {
214 // DISPLAY ERROR INWORLD 217 // DISPLAY ERROR INWORLD
215 string text = "Error compiling script:\r\n" + 218 string text = "Error compiling script:\n" +
216 e.Message.ToString(); 219 e.Message.ToString();
217 if (text.Length > 1100) 220 if (text.Length > 1100)
218 text = text.Substring(0, 1099); 221 text = text.Substring(0, 1099);
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
index efb05d3..6273da9 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/ICompiler.cs
@@ -33,7 +33,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
33{ 33{
34 public interface ICompiler 34 public interface ICompiler
35 { 35 {
36 void Configure(IConfig configSource); 36 string PerformScriptCompile(string source, string asset);
37 void Compile(string text, string outFile, List<IScriptApi> apiList); 37 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
38 LineMap();
38 } 39 }
39} 40}
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 0c807a8..dee7970 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -96,5 +96,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
96 void DestroyScriptInstance(); 96 void DestroyScriptInstance();
97 97
98 IScriptApi GetApi(string name); 98 IScriptApi GetApi(string name);
99
100 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap
101 { get; set; }
99 } 102 }
100} 103}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 86d6188..e8f2b71 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -89,7 +89,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
89 ResetCounters(); 89 ResetCounters();
90 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); 90 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true));
91 // Obviously this needs to be in a try/except block. 91 // Obviously this needs to be in a try/except block.
92 LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); 92 LSL2CSCodeTransformer codeTransformer;
93 try
94 {
95 codeTransformer = new LSL2CSCodeTransformer(p.Parse(script));
96 }
97 catch (CSToolsException e)
98 {
99 string message;
100
101 // LL start numbering lines at 0 - geeks!
102 //
103 message = String.Format("Line ({0},{1}) {2}",
104 e.slInfo.lineNumber - 1,
105 e.slInfo.charPosition - 1, e.Message);
106
107 throw new Exception(message);
108 }
109
93 m_astRoot = codeTransformer.Transform(); 110 m_astRoot = codeTransformer.Transform();
94 111
95 string retstr = String.Empty; 112 string retstr = String.Empty;
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index ec864e1..c6026fb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -38,7 +38,7 @@ using OpenSim.Region.ScriptEngine.Interfaces;
38 38
39namespace OpenSim.Region.ScriptEngine.Shared.CodeTools 39namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
40{ 40{
41 public class Compiler 41 public class Compiler : ICompiler
42 { 42 {
43 // private static readonly log4net.ILog m_log 43 // private static readonly log4net.ILog m_log
44 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 44 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -255,18 +255,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
255 /// <returns>Filename to .dll assembly</returns> 255 /// <returns>Filename to .dll assembly</returns>
256 public string PerformScriptCompile(string Script, string asset) 256 public string PerformScriptCompile(string Script, string asset)
257 { 257 {
258 m_positionMap = null;
259
258 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( 260 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
259 m_scriptEngine.World.RegionInfo.RegionID.ToString(), 261 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
260 FilePrefix + "_compiled_" + asset + ".dll")); 262 FilePrefix + "_compiled_" + asset + ".dll"));
261// string OutFile = Path.Combine(ScriptEnginesPath, 263// string OutFile = Path.Combine(ScriptEnginesPath,
262// FilePrefix + "_compiled_" + asset + ".dll"); 264// FilePrefix + "_compiled_" + asset + ".dll");
263 265
264 if (File.Exists(OutFile))
265 {
266 m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset);
267 return OutFile;
268 }
269
270 if (!Directory.Exists(ScriptEnginesPath)) 266 if (!Directory.Exists(ScriptEnginesPath))
271 { 267 {
272 try 268 try
@@ -327,38 +323,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
327 compileScript = LSL_Converter.Convert(Script); 323 compileScript = LSL_Converter.Convert(Script);
328 324
329 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; 325 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
326 }
330 327
331 l = enumCompileType.cs; 328 // Check this late so the map is generated on sim start
329 //
330 if (File.Exists(OutFile))
331 {
332 m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset);
333 return OutFile;
332 } 334 }
333 335
334 if (l == enumCompileType.yp) 336 if (l == enumCompileType.yp)
335 { 337 {
336 // Its YP, convert it to C# 338 // Its YP, convert it to C#
337 compileScript = YP_Converter.Convert(Script); 339 compileScript = YP_Converter.Convert(Script);
338 // We have our own processor now
339 //l = enumCompileType.cs;
340 }
341
342 // Insert additional assemblies here
343
344 //ADAM: Disabled for the moment until it's working right.
345 bool enableCommanderLSL = false;
346
347 if (enableCommanderLSL == true && ((l == enumCompileType.cs) || (l == enumCompileType.yp)))
348 {
349 foreach (KeyValuePair<string,
350 ICommander> com
351 in m_scriptEngine.World.GetCommanders())
352 {
353 compileScript = com.Value.GenerateRuntimeAPI() + compileScript;
354 }
355 } 340 }
356 341
357 // End of insert
358
359 switch (l) 342 switch (l)
360 { 343 {
361 case enumCompileType.cs: 344 case enumCompileType.cs:
345 case enumCompileType.lsl:
362 compileScript = CreateCSCompilerScript(compileScript); 346 compileScript = CreateCSCompilerScript(compileScript);
363 break; 347 break;
364 case enumCompileType.vb: 348 case enumCompileType.vb:
@@ -372,10 +356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
372 break; 356 break;
373 } 357 }
374 358
375// m_log.Debug("[ScriptEngine.DotNetEngine]: Preparing to compile the following LSL to C# translated code");
376// m_log.Debug("");
377// m_log.Debug(compileScript);
378
379 return CompileFromDotNetText(compileScript, l, asset); 359 return CompileFromDotNetText(compileScript, l, asset);
380 } 360 }
381 361
@@ -442,26 +422,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
442 // Output assembly name 422 // Output assembly name
443 scriptCompileCounter++; 423 scriptCompileCounter++;
444 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( 424 string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine(
445 m_scriptEngine.World.RegionInfo.RegionID.ToString(), 425 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
446 FilePrefix + "_compiled_" + asset + ".dll")); 426 FilePrefix + "_compiled_" + asset + ".dll"));
447#if DEBUG
448// m_scriptEngine.Log.Debug("[Compiler]: Starting compile of \"" + OutFile + "\".");
449#endif
450 try 427 try
451 { 428 {
452 File.Delete(OutFile); 429 File.Delete(OutFile);
453 } 430 }
454 catch (Exception e) // NOTLEGIT - Should be just catching FileIOException 431 catch (Exception e) // NOTLEGIT - Should be just FileIOException
455 { 432 {
456 //m_scriptEngine.Log.Error("[Compiler]: Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); 433 throw new Exception("Unable to delete old existing "+
457 throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); 434 "script-file before writing new. Compile aborted: " +
435 e.ToString());
458 } 436 }
459 //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
460 437
461 // DEBUG - write source to disk 438 // DEBUG - write source to disk
462 if (WriteScriptSourceToDebugFile) 439 if (WriteScriptSourceToDebugFile)
463 { 440 {
464 string srcFileName = FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext; 441 string srcFileName = FilePrefix + "_source_" +
442 Path.GetFileNameWithoutExtension(OutFile) + ext;
465 try 443 try
466 { 444 {
467 File.WriteAllText(Path.Combine(Path.Combine( 445 File.WriteAllText(Path.Combine(Path.Combine(
@@ -469,9 +447,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
469 m_scriptEngine.World.RegionInfo.RegionID.ToString()), 447 m_scriptEngine.World.RegionInfo.RegionID.ToString()),
470 srcFileName), Script); 448 srcFileName), Script);
471 } 449 }
472 catch (Exception ex) // NOTLEGIT - Should be just catching FileIOException 450 catch (Exception ex) //NOTLEGIT - Should be just FileIOException
473 { 451 {
474 m_scriptEngine.Log.Error("[Compiler]: Exception while trying to write script source to file \"" + srcFileName + "\": " + ex.ToString()); 452 m_scriptEngine.Log.Error("[Compiler]: Exception while "+
453 "trying to write script source to file \"" +
454 srcFileName + "\": " + ex.ToString());
475 } 455 }
476 } 456 }
477 457
@@ -480,22 +460,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
480 460
481 parameters.IncludeDebugInformation = true; 461 parameters.IncludeDebugInformation = true;
482 462
483 // Add all available assemblies 463 string rootPath =
484// foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) 464 Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
485// {
486// Console.WriteLine("Adding assembly: " + asm.Location);
487// parameters.ReferencedAssemblies.Add(asm.Location);
488// }
489 465
490 string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); 466 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
491 // string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location); 467 "OpenSim.Region.ScriptEngine.Shared.dll"));
492 //Console.WriteLine("Assembly location: " + rootPath); 468 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
493 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll")); 469 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
494 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
495 470
496 if (lang == enumCompileType.yp) 471 if (lang == enumCompileType.yp)
497 { 472 {
498 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); 473 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
474 "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll"));
499 } 475 }
500 476
501 parameters.GenerateExecutable = false; 477 parameters.GenerateExecutable = false;
@@ -504,24 +480,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
504 //parameters.WarningLevel = 1; // Should be 4? 480 //parameters.WarningLevel = 1; // Should be 4?
505 parameters.TreatWarningsAsErrors = false; 481 parameters.TreatWarningsAsErrors = false;
506 482
507//Console.WriteLine(Script);
508 CompilerResults results; 483 CompilerResults results;
509 switch (lang) 484 switch (lang)
510 { 485 {
511 case enumCompileType.vb: 486 case enumCompileType.vb:
512 results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script); 487 results = VBcodeProvider.CompileAssemblyFromSource(
488 parameters, Script);
513 break; 489 break;
514 case enumCompileType.cs: 490 case enumCompileType.cs:
515 results = CScodeProvider.CompileAssemblyFromSource(parameters, Script); 491 case enumCompileType.lsl:
492 results = CScodeProvider.CompileAssemblyFromSource(
493 parameters, Script);
516 break; 494 break;
517 case enumCompileType.js: 495 case enumCompileType.js:
518 results = JScodeProvider.CompileAssemblyFromSource(parameters, Script); 496 results = JScodeProvider.CompileAssemblyFromSource(
497 parameters, Script);
519 break; 498 break;
520 case enumCompileType.yp: 499 case enumCompileType.yp:
521 results = YPcodeProvider.CompileAssemblyFromSource(parameters, Script); 500 results = YPcodeProvider.CompileAssemblyFromSource(
501 parameters, Script);
522 break; 502 break;
523 default: 503 default:
524 throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\""); 504 throw new Exception("Compiler is not able to recongnize "+
505 "language type \"" + lang.ToString() + "\"");
525 } 506 }
526 507
527 // Check result 508 // Check result
@@ -530,11 +511,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
530 // 511 //
531 // WARNINGS AND ERRORS 512 // WARNINGS AND ERRORS
532 // 513 //
514 int display = 5;
533 if (results.Errors.Count > 0) 515 if (results.Errors.Count > 0)
534 { 516 {
535 string errtext = String.Empty; 517 string errtext = String.Empty;
536 foreach (CompilerError CompErr in results.Errors) 518 foreach (CompilerError CompErr in results.Errors)
537 { 519 {
520 // Show 5 errors max
521 //
522 if (display <= 0)
523 break;
524 display--;
525
538 string severity = "Error"; 526 string severity = "Error";
539 if ( CompErr.IsWarning ) 527 if ( CompErr.IsWarning )
540 { 528 {
@@ -543,22 +531,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
543 531
544 KeyValuePair<int, int> lslPos; 532 KeyValuePair<int, int> lslPos;
545 533
546 try 534 lslPos = FindErrorPosition(CompErr.Line, CompErr.Column);
547 { 535
548 lslPos = m_positionMap[new KeyValuePair<int, int>(CompErr.Line, CompErr.Column)]; 536 string text = CompErr.ErrorText;
549 } 537
550 catch (KeyNotFoundException) // we don't have this line/column mapped 538 // Use LSL type names
551 { 539 if (lang == enumCompileType.lsl)
552 m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column)); 540 text = ReplaceTypes(CompErr.ErrorText);
553 lslPos = new KeyValuePair<int, int>(-CompErr.Line, -CompErr.Column);
554 }
555 541
556 // The Second Life viewer's script editor begins 542 // The Second Life viewer's script editor begins
557 // countingn lines and columns at 0, so we subtract 1. 543 // countingn lines and columns at 0, so we subtract 1.
558 errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity); 544 errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n",
545 lslPos.Key - 1, lslPos.Value - 1,
546 CompErr.ErrorNumber, text, severity);
559 } 547 }
560 548
561 Console.WriteLine("[COMPILER MESSAGES]: " + errtext);
562 if (!File.Exists(OutFile)) 549 if (!File.Exists(OutFile))
563 { 550 {
564 throw new Exception(errtext); 551 throw new Exception(errtext);
@@ -574,8 +561,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
574 errtext += "No compile error. But not able to locate compiled file."; 561 errtext += "No compile error. But not able to locate compiled file.";
575 throw new Exception(errtext); 562 throw new Exception(errtext);
576 } 563 }
577 m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly for {0}", asset); 564 m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly "+
565 "for {0}", asset);
578 return OutFile; 566 return OutFile;
579 } 567 }
568
569 public KeyValuePair<int, int> FindErrorPosition(int line, int col)
570 {
571 return FindErrorPosition(line, col, m_positionMap);
572 }
573
574 private class kvpSorter : IComparer<KeyValuePair<int,int>>
575 {
576 public int Compare(KeyValuePair<int,int> a,
577 KeyValuePair<int,int> b)
578 {
579 return a.Key.CompareTo(b.Key);
580 }
581 }
582
583 public static KeyValuePair<int, int> FindErrorPosition(int line,
584 int col, Dictionary<KeyValuePair<int, int>,
585 KeyValuePair<int, int>> positionMap)
586 {
587 if (positionMap == null || positionMap.Count == 0)
588 return new KeyValuePair<int, int>(line, col);
589
590 KeyValuePair<int, int> ret = new KeyValuePair<int, int>();
591
592 if (positionMap.TryGetValue(new KeyValuePair<int, int>(line, col),
593 out ret))
594 return ret;
595
596 List<KeyValuePair<int,int>> sorted =
597 new List<KeyValuePair<int,int>>(positionMap.Keys);
598
599 sorted.Sort(new kvpSorter());
600
601 int l = 1;
602 int c = 1;
603
604 foreach (KeyValuePair<int, int> cspos in sorted)
605 {
606 if (cspos.Key >= line)
607 {
608 if (cspos.Key > line)
609 return new KeyValuePair<int, int>(l, c);
610 if (cspos.Value > col)
611 return new KeyValuePair<int, int>(l, c);
612 c = cspos.Value;
613 if (c == 0)
614 c++;
615 }
616 else
617 {
618 l = cspos.Key;
619 }
620 }
621 return new KeyValuePair<int, int>(l, c);
622 }
623
624 string ReplaceTypes(string message)
625 {
626 message = message.Replace(
627 "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString",
628 "string");
629
630 message = message.Replace(
631 "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger",
632 "integer");
633
634 message = message.Replace(
635 "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat",
636 "float");
637
638 message = message.Replace(
639 "OpenSim.Region.ScriptEngine.Shared.LSL_Types.list",
640 "list");
641
642 return message;
643 }
644
645 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
646 LineMap()
647 {
648 if (m_positionMap == null)
649 return null;
650
651 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ret =
652 new Dictionary<KeyValuePair<int,int>, KeyValuePair<int, int>>();
653
654 foreach (KeyValuePair<int, int> kvp in m_positionMap.Keys)
655 ret.Add(kvp, m_positionMap[kvp]);
656
657 return ret;
658 }
580 } 659 }
581} 660}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index c8d60af..aa9ace4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -80,6 +80,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
80 private int m_ControlEventsInQueue = 0; 80 private int m_ControlEventsInQueue = 0;
81 private int m_LastControlLevel = 0; 81 private int m_LastControlLevel = 0;
82 private bool m_CollisionInQueue = false; 82 private bool m_CollisionInQueue = false;
83 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
84 m_LineMap;
85
86 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
87 LineMap
88 {
89 get { return m_LineMap; }
90 set { m_LineMap = value; }
91 }
83 92
84 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 93 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
85 94
@@ -628,7 +637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
628 try 637 try
629 { 638 {
630 // DISPLAY ERROR INWORLD 639 // DISPLAY ERROR INWORLD
631 string text = "Runtime error:\n" + e.InnerException.ToString(); 640 string text = FormatException(e);
641
632 if (text.Length > 1000) 642 if (text.Length > 1000)
633 text = text.Substring(0, 1000); 643 text = text.Substring(0, 1000);
634 m_Engine.World.SimChat(Utils.StringToBytes(text), 644 m_Engine.World.SimChat(Utils.StringToBytes(text),
@@ -812,5 +822,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
812 { 822 {
813 return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName); 823 return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName);
814 } 824 }
825
826 string FormatException(Exception e)
827 {
828 string message = "Runtime error:\n" + e.InnerException.StackTrace;
829 string[] lines = message.Split(new char[] {'\n'});
830
831 foreach (string line in lines)
832 {
833 if (line.Contains("SecondLife.Script"))
834 {
835 int idx = line.IndexOf(':');
836 if (idx != -1)
837 {
838 string val = line.Substring(idx+1);
839 int lineNum = 0;
840 if (int.TryParse(val, out lineNum))
841 {
842 KeyValuePair<int, int> pos =
843 Compiler.FindErrorPosition(
844 lineNum, 0, LineMap);
845
846 int scriptLine = pos.Key;
847 int col = pos.Value;
848 if (scriptLine == 0)
849 scriptLine++;
850 if (col == 0)
851 col++;
852 message = string.Format("Runtime error:\n" +
853 "Line ({0}): {1}", scriptLine - 1,
854 e.InnerException.Message);
855
856 return message;
857 }
858 }
859 }
860 }
861
862 return message;
863 }
815 } 864 }
816} 865}
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index a37cbb4..6bafd69 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
59 private int m_MaxScriptQueue; 59 private int m_MaxScriptQueue;
60 private Scene m_Scene; 60 private Scene m_Scene;
61 private IConfig m_ScriptConfig; 61 private IConfig m_ScriptConfig;
62 private Compiler m_Compiler; 62 private ICompiler m_Compiler;
63 private int m_MinThreads; 63 private int m_MinThreads;
64 private int m_MaxThreads ; 64 private int m_MaxThreads ;
65 private int m_IdleTimeout; 65 private int m_IdleTimeout;
@@ -510,7 +510,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
510 try 510 try
511 { 511 {
512 // DISPLAY ERROR INWORLD 512 // DISPLAY ERROR INWORLD
513 string text = "Error compiling script:\r\n" + e.Message.ToString(); 513 string text = "Error compiling script:\n" + e.ToString();
514 if (text.Length > 1000) 514 if (text.Length > 1000)
515 text = text.Substring(0, 1000); 515 text = text.Substring(0, 1000);
516 World.SimChat(Utils.StringToBytes(text), 516 World.SimChat(Utils.StringToBytes(text),
@@ -585,6 +585,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
585 part.ParentGroup.RootPart.Name, item.Name); 585 part.ParentGroup.RootPart.Name, item.Name);
586 586
587 instance.AppDomain = appDomain; 587 instance.AppDomain = appDomain;
588 instance.LineMap = m_Compiler.LineMap();
588 589
589 m_Scripts[itemID] = instance; 590 m_Scripts[itemID] = instance;
590 } 591 }