aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2018-02-25 00:18:41 +0000
committerUbitUmarov2018-02-25 00:18:41 +0000
commit85b973ce1d8dc034546c9c572a7f57e73b6017d3 (patch)
treea03332d9233e3788f8bc2e535b6863d8fe195b0b
parentYengine fix its section name on opensim.ini.example (diff)
downloadopensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.zip
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.gz
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.bz2
opensim-SC-85b973ce1d8dc034546c9c572a7f57e73b6017d3.tar.xz
Y(xmr)engine cosmetics...
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs1951
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs187
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs41
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs30
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs662
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs1518
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs98
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs97
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs64
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs61
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs333
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs79
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs387
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs198
19 files changed, 2058 insertions, 3776 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs
index 5d1cbc0..ca7c372 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs
@@ -35,7 +35,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
35 35
36 public class InternalFuncDict: VarDict 36 public class InternalFuncDict: VarDict
37 { 37 {
38
39 /** 38 /**
40 * @brief build dictionary of internal functions from an interface. 39 * @brief build dictionary of internal functions from an interface.
41 * @param iface = interface with function definitions 40 * @param iface = interface with function definitions
@@ -46,27 +45,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
46 public InternalFuncDict(Type iface, bool inclSig) 45 public InternalFuncDict(Type iface, bool inclSig)
47 : base(false) 46 : base(false)
48 { 47 {
49 /* 48 // Loop through list of all methods declared in the interface.
50 * Loop through list of all methods declared in the interface.
51 */
52 System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods(); 49 System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods();
53 foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods) 50 foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods)
54 { 51 {
55 string key = ifaceMethod.Name; 52 string key = ifaceMethod.Name;
56 53
57 /* 54 // Only do ones that begin with lower-case letters...
58 * Only do ones that begin with lower-case letters... 55 // as any others can't be referenced by scripts
59 * as any others can't be referenced by scripts
60 */
61 if((key[0] < 'a') || (key[0] > 'z')) 56 if((key[0] < 'a') || (key[0] > 'z'))
62 continue; 57 continue;
63 58
64 try 59 try
65 { 60 {
66 61 // Create a corresponding TokenDeclVar struct.
67 /*
68 * Create a corresponding TokenDeclVar struct.
69 */
70 System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters(); 62 System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters();
71 TokenArgDecl argDecl = new TokenArgDecl(null); 63 TokenArgDecl argDecl = new TokenArgDecl(null);
72 for(int i = 0; i < parameters.Length; i++) 64 for(int i = 0; i < parameters.Length; i++)
@@ -81,9 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
81 declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType); 73 declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType);
82 declFunc.argDecl = argDecl; 74 declFunc.argDecl = argDecl;
83 75
84 /* 76 // Add the TokenDeclVar struct to the dictionary.
85 * Add the TokenDeclVar struct to the dictionary.
86 */
87 this.AddEntry(declFunc); 77 this.AddEntry(declFunc);
88 } 78 }
89 catch(Exception except) 79 catch(Exception except)
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
index a480263..ea86b0b 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs
@@ -77,9 +77,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
77 public static Type xmrInstSuperType = null; // typeof whatever is actually malloc'd for script instances 77 public static Type xmrInstSuperType = null; // typeof whatever is actually malloc'd for script instances
78 // - must inherit from XMRInstAbstract 78 // - must inherit from XMRInstAbstract
79 79
80 /* 80 // Static tables that there only needs to be one copy of for all.
81 * Static tables that there only needs to be one copy of for all.
82 */
83 private static VarDict legalEventHandlers = CreateLegalEventHandlers(); 81 private static VarDict legalEventHandlers = CreateLegalEventHandlers();
84 private static CompValu[] zeroCompValus = new CompValu[0]; 82 private static CompValu[] zeroCompValus = new CompValu[0];
85 private static TokenType[] zeroArgs = new TokenType[0]; 83 private static TokenType[] zeroArgs = new TokenType[0];
@@ -161,20 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
161 159
162 public static bool CodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash) 160 public static bool CodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash)
163 { 161 {
164 /* 162 // Run compiler such that it has a 'this' context for convenience.
165 * Run compiler such that it has a 'this' context for convenience.
166 */
167 ScriptCodeGen scg = new ScriptCodeGen(tokenScript, objFileWriter, sourceHash); 163 ScriptCodeGen scg = new ScriptCodeGen(tokenScript, objFileWriter, sourceHash);
168 164
169 /* 165 // Return pointer to resultant script object code.
170 * Return pointer to resultant script object code.
171 */
172 return !scg.youveAnError; 166 return !scg.youveAnError;
173 } 167 }
174 168
175 /* 169 // There is one set of these variables for each script being compiled.
176 * There is one set of these variables for each script being compiled.
177 */
178 private bool mightGetHere = false; 170 private bool mightGetHere = false;
179 private bool youveAnError = false; 171 private bool youveAnError = false;
180 private BreakContTarg curBreakTarg = null; 172 private BreakContTarg curBreakTarg = null;
@@ -246,24 +238,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
246 */ 238 */
247 private void PerformCompilation() 239 private void PerformCompilation()
248 { 240 {
249 /* 241 // errorMessageToken is used only when the given token doesn't have a
250 * errorMessageToken is used only when the given token doesn't have a 242 // output delegate associated with it such as for backend API functions
251 * output delegate associated with it such as for backend API functions 243 // that only have one copy for the whole system. It is kept up-to-date
252 * that only have one copy for the whole system. It is kept up-to-date 244 // approximately but is rarely needed so going to assume it doesn't have
253 * approximately but is rarely needed so going to assume it doesn't have 245 // to be exact.
254 * to be exact.
255 */
256 errorMessageToken = tokenScript; 246 errorMessageToken = tokenScript;
257 247
258 /* 248 // Set up dictionary to translate state names to their index number.
259 * Set up dictionary to translate state names to their index number.
260 */
261 stateIndices = new Dictionary<string, int>(); 249 stateIndices = new Dictionary<string, int>();
262 250
263 /* 251 // Assign each state its own unique index.
264 * Assign each state its own unique index. 252 // The default state gets 0.
265 * The default state gets 0.
266 */
267 nStates = 0; 253 nStates = 0;
268 tokenScript.defaultState.body.index = nStates++; 254 tokenScript.defaultState.body.index = nStates++;
269 stateIndices.Add("default", 0); 255 stateIndices.Add("default", 0);
@@ -274,9 +260,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
274 stateIndices.Add(declState.name.val, declState.body.index); 260 stateIndices.Add(declState.name.val, declState.body.index);
275 } 261 }
276 262
277 /* 263 // Make up an array that translates state indices to state name strings.
278 * Make up an array that translates state indices to state name strings.
279 */
280 stateNames = new string[nStates]; 264 stateNames = new string[nStates];
281 stateNames[0] = "default"; 265 stateNames[0] = "default";
282 foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) 266 foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states)
@@ -285,11 +269,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
285 stateNames[declState.body.index] = declState.name.val; 269 stateNames[declState.body.index] = declState.name.val;
286 } 270 }
287 271
288 /* 272 // Make sure we have delegates for all script-defined functions and methods,
289 * Make sure we have delegates for all script-defined functions and methods, 273 // creating anonymous ones if needed. Note that this includes all property
290 * creating anonymous ones if needed. Note that this includes all property 274 // getter and setter methods.
291 * getter and setter methods.
292 */
293 foreach(TokenDeclVar declFunc in tokenScript.variablesStack) 275 foreach(TokenDeclVar declFunc in tokenScript.variablesStack)
294 { 276 {
295 if(declFunc.retType != null) 277 if(declFunc.retType != null)
@@ -347,42 +329,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
347 } 329 }
348 } 330 }
349 331
350 /* 332 // No more types can be defined or we won't be able to write them to the object file.
351 * No more types can be defined or we won't be able to write them to the object file.
352 */
353 tokenScript.sdSrcTypesSeal(); 333 tokenScript.sdSrcTypesSeal();
354 334
355 /* 335 // Assign all global variables a slot in its corresponding XMRInstance.gbl<Type>s[] array.
356 * Assign all global variables a slot in its corresponding XMRInstance.gbl<Type>s[] array. 336 // Global variables are simply elements of those arrays at runtime, thus we don't need to create
357 * Global variables are simply elements of those arrays at runtime, thus we don't need to create 337 // an unique class for each script, we can just use XMRInstance as is for all.
358 * an unique class for each script, we can just use XMRInstance as is for all.
359 */
360 foreach(TokenDeclVar declVar in tokenScript.variablesStack) 338 foreach(TokenDeclVar declVar in tokenScript.variablesStack)
361 { 339 {
362 340 // Omit 'constant' variables as they are coded inline so don't need a slot.
363 /*
364 * Omit 'constant' variables as they are coded inline so don't need a slot.
365 */
366 if(declVar.constant) 341 if(declVar.constant)
367 continue; 342 continue;
368 343
369 /* 344 // Do functions later.
370 * Do functions later.
371 */
372 if(declVar.retType != null) 345 if(declVar.retType != null)
373 continue; 346 continue;
374 347
375 /* 348 // Create entry in the value array for the variable or property.
376 * Create entry in the value array for the variable or property.
377 */
378 declVar.location = new CompValuGlobalVar(declVar, glblSizes); 349 declVar.location = new CompValuGlobalVar(declVar, glblSizes);
379 } 350 }
380 351
381 /* 352 // Likewise for any static fields in script-defined classes.
382 * Likewise for any static fields in script-defined classes. 353 // They can be referenced anywhere by <typename>.<fieldname>, see
383 * They can be referenced anywhere by <typename>.<fieldname>, see 354 // GenerateFromLValSField().
384 * GenerateFromLValSField().
385 */
386 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) 355 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
387 { 356 {
388 if(!(sdType is TokenDeclSDTypeClass)) 357 if(!(sdType is TokenDeclSDTypeClass))
@@ -391,40 +360,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
391 360
392 foreach(TokenDeclVar declVar in sdtClass.members) 361 foreach(TokenDeclVar declVar in sdtClass.members)
393 { 362 {
394 363 // Omit 'constant' variables as they are coded inline so don't need a slot.
395 /*
396 * Omit 'constant' variables as they are coded inline so don't need a slot.
397 */
398 if(declVar.constant) 364 if(declVar.constant)
399 continue; 365 continue;
400 366
401 /* 367 // Do methods later.
402 * Do methods later.
403 */
404 if(declVar.retType != null) 368 if(declVar.retType != null)
405 continue; 369 continue;
406 370
407 /* 371 // Ignore non-static fields for now.
408 * Ignore non-static fields for now. 372 // They get assigned below.
409 * They get assigned below.
410 */
411 if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0) 373 if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0)
412 continue; 374 continue;
413 375
414 /* 376 // Create entry in the value array for the static field or static property.
415 * Create entry in the value array for the static field or static property.
416 */
417 declVar.location = new CompValuGlobalVar(declVar, glblSizes); 377 declVar.location = new CompValuGlobalVar(declVar, glblSizes);
418 } 378 }
419 } 379 }
420 380
421 /* 381 // Assign slots for all interface method prototypes.
422 * Assign slots for all interface method prototypes. 382 // These indices are used to index the array of delegates that holds a class' implementation of an
423 * These indices are used to index the array of delegates that holds a class' implementation of an 383 // interface.
424 * interface. 384 // Properties do not get a slot because they aren't called as such. But their corresponding
425 * Properties do not get a slot because they aren't called as such. But their corresponding 385 // <name>$get() and <name>$set(<type>) methods are in the table and they each get a slot.
426 * <name>$get() and <name>$set(<type>) methods are in the table and they each get a slot.
427 */
428 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) 386 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
429 { 387 {
430 if(!(sdType is TokenDeclSDTypeInterface)) 388 if(!(sdType is TokenDeclSDTypeInterface))
@@ -440,9 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
440 } 398 }
441 } 399 }
442 400
443 /* 401 // Assign slots for all instance fields and virtual methods of script-defined classes.
444 * Assign slots for all instance fields and virtual methods of script-defined classes.
445 */
446 int maxExtends = tokenScript.sdSrcTypesCount; 402 int maxExtends = tokenScript.sdSrcTypesCount;
447 bool didOne; 403 bool didOne;
448 do 404 do
@@ -456,10 +412,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
456 if(sdtClass.slotsAssigned) 412 if(sdtClass.slotsAssigned)
457 continue; 413 continue;
458 414
459 /* 415 // If this class extends another, the extended class has to already
460 * If this class extends another, the extended class has to already 416 // be set up, because our slots add on to the end of the extended class.
461 * be set up, because our slots add on to the end of the extended class.
462 */
463 TokenDeclSDTypeClass extends = sdtClass.extends; 417 TokenDeclSDTypeClass extends = sdtClass.extends;
464 if(extends != null) 418 if(extends != null)
465 { 419 {
@@ -483,10 +437,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
483 } 437 }
484 } 438 }
485 439
486 /* 440 // Extended class's slots all assigned, assign our instance fields
487 * Extended class's slots all assigned, assign our instance fields 441 // slots in the XMRSDTypeClObj arrays.
488 * slots in the XMRSDTypeClObj arrays.
489 */
490 foreach(TokenDeclVar declVar in sdtClass.members) 442 foreach(TokenDeclVar declVar in sdtClass.members)
491 { 443 {
492 if(declVar.retType != null) 444 if(declVar.retType != null)
@@ -501,31 +453,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
501 } 453 }
502 } 454 }
503 455
504 /* 456 // ... and assign virtual method vtable slots.
505 * ... and assign virtual method vtable slots. 457 //
506 * 458 // - : error if any overridden method, doesn't need a slot
507 * - : error if any overridden method, doesn't need a slot 459 // abstract : error if any overridden method, alloc new slot but leave it empty
508 * abstract : error if any overridden method, alloc new slot but leave it empty 460 // new : ignore any overridden method, doesn't need a slot
509 * new : ignore any overridden method, doesn't need a slot 461 // new abstract : ignore any overridden method, alloc new slot but leave it empty
510 * new abstract : ignore any overridden method, alloc new slot but leave it empty 462 // override : must have overridden abstract/virtual, use old slot
511 * override : must have overridden abstract/virtual, use old slot 463 // override abstract : must have overridden abstract, use old slot but it is still empty
512 * override abstract : must have overridden abstract, use old slot but it is still empty 464 // static : error if any overridden method, doesn't need a slot
513 * static : error if any overridden method, doesn't need a slot 465 // static new : ignore any overridden method, doesn't need a slot
514 * static new : ignore any overridden method, doesn't need a slot 466 // virtual : error if any overridden method, alloc new slot and fill it in
515 * virtual : error if any overridden method, alloc new slot and fill it in 467 // virtual new : ignore any overridden method, alloc new slot and fill it in
516 * virtual new : ignore any overridden method, alloc new slot and fill it in
517 */
518 foreach(TokenDeclVar declFunc in sdtClass.members) 468 foreach(TokenDeclVar declFunc in sdtClass.members)
519 { 469 {
520 if(declFunc.retType == null) 470 if(declFunc.retType == null)
521 continue; 471 continue;
522 curDeclFunc = declFunc; 472 curDeclFunc = declFunc;
523 473
524 /* 474 // See if there is a method in an extended class that this method overshadows.
525 * See if there is a method in an extended class that this method overshadows. 475 // If so, check for various conflicts.
526 * If so, check for various conflicts. 476 // In any case, SDT_NEW on our method means to ignore any overshadowed method.
527 * In any case, SDT_NEW on our method means to ignore any overshadowed method.
528 */
529 string declLongName = sdtClass.longName.val + "." + declFunc.funcNameSig.val; 477 string declLongName = sdtClass.longName.val + "." + declFunc.funcNameSig.val;
530 uint declFlags = declFunc.sdtFlags; 478 uint declFlags = declFunc.sdtFlags;
531 TokenDeclVar overridden = null; 479 TokenDeclVar overridden = null;
@@ -544,9 +492,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
544 string overLongName = overridden.sdtClass.longName.val; 492 string overLongName = overridden.sdtClass.longName.val;
545 uint overFlags = overridden.sdtFlags; 493 uint overFlags = overridden.sdtFlags;
546 494
547 /* 495 // See if overridden method allows itself to be overridden.
548 * See if overridden method allows itself to be overridden.
549 */
550 if((overFlags & ScriptReduce.SDT_ABSTRACT) != 0) 496 if((overFlags & ScriptReduce.SDT_ABSTRACT) != 0)
551 { 497 {
552 if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE)) == 0) 498 if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE)) == 0)
@@ -573,9 +519,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
573 break; 519 break;
574 } 520 }
575 521
576 /* 522 // See if our method is capable of overriding the other method.
577 * See if our method is capable of overriding the other method.
578 */
579 if((declFlags & ScriptReduce.SDT_ABSTRACT) != 0) 523 if((declFlags & ScriptReduce.SDT_ABSTRACT) != 0)
580 { 524 {
581 if((overFlags & ScriptReduce.SDT_ABSTRACT) == 0) 525 if((overFlags & ScriptReduce.SDT_ABSTRACT) == 0)
@@ -599,9 +543,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
599 } 543 }
600 } while(false); 544 } while(false);
601 545
602 /* 546 // Now we can assign it a vtable slot if it needs one (ie, it is virtual).
603 * Now we can assign it a vtable slot if it needs one (ie, it is virtual).
604 */
605 declFunc.vTableIndex = -1; 547 declFunc.vTableIndex = -1;
606 if(overridden != null) 548 if(overridden != null)
607 { 549 {
@@ -618,11 +560,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
618 } 560 }
619 curDeclFunc = null; 561 curDeclFunc = null;
620 562
621 /* 563 // ... and assign implemented interface slots.
622 * ... and assign implemented interface slots. 564 // Note that our implementations of a given interface is completely independent of any
623 * Note that our implementations of a given interface is completely independent of any 565 // rootward class's implementation of that same interface.
624 * rootward class's implementation of that same interface.
625 */
626 int nIFaces = sdtClass.numInterfaces + sdtClass.implements.Count; 566 int nIFaces = sdtClass.numInterfaces + sdtClass.implements.Count;
627 sdtClass.iFaces = new TokenDeclSDTypeInterface[nIFaces]; 567 sdtClass.iFaces = new TokenDeclSDTypeInterface[nIFaces];
628 sdtClass.iImplFunc = new TokenDeclVar[nIFaces][]; 568 sdtClass.iImplFunc = new TokenDeclVar[nIFaces][];
@@ -653,11 +593,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
653 curDeclFunc = classMeth; 593 curDeclFunc = classMeth;
654 for(TokenIntfImpl intfImpl = classMeth.implements; intfImpl != null; intfImpl = (TokenIntfImpl)intfImpl.nextToken) 594 for(TokenIntfImpl intfImpl = classMeth.implements; intfImpl != null; intfImpl = (TokenIntfImpl)intfImpl.nextToken)
655 { 595 {
656 596 // One of the class methods implements an interface method.
657 /* 597 // Try to find the interface method that is implemented and verify its signature.
658 * One of the class methods implements an interface method.
659 * Try to find the interface method that is implemented and verify its signature.
660 */
661 TokenDeclSDTypeInterface intfType = intfImpl.intfType.decl; 598 TokenDeclSDTypeInterface intfType = intfImpl.intfType.decl;
662 TokenDeclVar intfMeth = FindExactWithRet(intfType.methsNProps, intfImpl.methName, classMeth.retType, classMeth.argDecl.types); 599 TokenDeclVar intfMeth = FindExactWithRet(intfType.methsNProps, intfImpl.methName, classMeth.retType, classMeth.argDecl.types);
663 if(intfMeth == null) 600 if(intfMeth == null)
@@ -666,9 +603,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
666 continue; 603 continue;
667 } 604 }
668 605
669 /* 606 // See if this class was declared to implement that interface.
670 * See if this class was declared to implement that interface.
671 */
672 bool found = false; 607 bool found = false;
673 foreach(TokenDeclSDTypeInterface intf in sdtClass.implements) 608 foreach(TokenDeclSDTypeInterface intf in sdtClass.implements)
674 { 609 {
@@ -684,11 +619,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
684 continue; 619 continue;
685 } 620 }
686 621
687 /* 622 // Get index in iFaces[] and iImplFunc[] arrays.
688 * Get index in iFaces[] and iImplFunc[] arrays. 623 // Start scanning from the end in case one of our rootward classes also implements the interface.
689 * Start scanning from the end in case one of our rootward classes also implements the interface. 624 // We should always be successful because we know by now that this class implements the interface.
690 * We should always be successful because we know by now that this class implements the interface.
691 */
692 int i; 625 int i;
693 for(i = sdtClass.numInterfaces; --i >= 0;) 626 for(i = sdtClass.numInterfaces; --i >= 0;)
694 { 627 {
@@ -696,9 +629,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
696 break; 629 break;
697 } 630 }
698 631
699 /* 632 // Now remember which of the class methods implements that interface method.
700 * Now remember which of the class methods implements that interface method.
701 */
702 int j = intfMeth.vTableIndex; 633 int j = intfMeth.vTableIndex;
703 if(sdtClass.iImplFunc[i][j] != null) 634 if(sdtClass.iImplFunc[i][j] != null)
704 { 635 {
@@ -710,9 +641,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
710 } 641 }
711 curDeclFunc = null; 642 curDeclFunc = null;
712 643
713 /* 644 // Now make sure this class implements all methods for all declared interfaces.
714 * Now make sure this class implements all methods for all declared interfaces.
715 */
716 for(int i = sdtClass.numInterfaces - sdtClass.implements.Count; i < sdtClass.numInterfaces; i++) 645 for(int i = sdtClass.numInterfaces - sdtClass.implements.Count; i < sdtClass.numInterfaces; i++)
717 { 646 {
718 TokenDeclVar[] implementations = sdtClass.iImplFunc[i]; 647 TokenDeclVar[] implementations = sdtClass.iImplFunc[i];
@@ -735,18 +664,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
735 } 664 }
736 } 665 }
737 666
738 /* 667 // All slots for this class have been assigned.
739 * All slots for this class have been assigned.
740 */
741 sdtClass.slotsAssigned = true; 668 sdtClass.slotsAssigned = true;
742 didOne = true; 669 didOne = true;
743 } 670 }
744 } while(didOne); 671 } while(didOne);
745 672
746 /* 673 // Compute final values for all variables/fields declared as 'constant'.
747 * Compute final values for all variables/fields declared as 'constant'. 674 // Note that there may be forward references.
748 * Note that there may be forward references.
749 */
750 do 675 do
751 { 676 {
752 didOne = false; 677 didOne = false;
@@ -773,9 +698,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
773 currentSDTClass = null; 698 currentSDTClass = null;
774 } while(didOne); 699 } while(didOne);
775 700
776 /* 701 // Now we should be able to assign all those constants their type and location.
777 * Now we should be able to assign all those constants their type and location.
778 */
779 foreach(TokenDeclVar tdv in tokenScript.variablesStack) 702 foreach(TokenDeclVar tdv in tokenScript.variablesStack)
780 { 703 {
781 if(tdv.constant) 704 if(tdv.constant)
@@ -816,20 +739,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
816 } 739 }
817 currentSDTClass = null; 740 currentSDTClass = null;
818 741
819 /* 742 // For all classes that define all the methods needed for the class, ie, they aren't abstract,
820 * For all classes that define all the methods needed for the class, ie, they aren't abstract, 743 // define a static class.$new() method with same args as the $ctor(s). This will allow the
821 * define a static class.$new() method with same args as the $ctor(s). This will allow the 744 // class to be instantiated via the new operator.
822 * class to be instantiated via the new operator.
823 */
824 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) 745 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
825 { 746 {
826 if(!(sdType is TokenDeclSDTypeClass)) 747 if(!(sdType is TokenDeclSDTypeClass))
827 continue; 748 continue;
828 TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; 749 TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType;
829 750
830 /* 751 // See if the class as it stands would be able to fill every slot of its vtable.
831 * See if the class as it stands would be able to fill every slot of its vtable.
832 */
833 bool[] filled = new bool[sdtClass.numVirtFuncs]; 752 bool[] filled = new bool[sdtClass.numVirtFuncs];
834 int numFilled = 0; 753 int numFilled = 0;
835 for(TokenDeclSDTypeClass sdtc = sdtClass; sdtc != null; sdtc = sdtc.extends) 754 for(TokenDeclSDTypeClass sdtc = sdtClass; sdtc != null; sdtc = sdtc.extends)
@@ -847,11 +766,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
847 } 766 }
848 } 767 }
849 768
850 /* 769 // If so, define a static class.$new() method for every constructor defined for the class.
851 * If so, define a static class.$new() method for every constructor defined for the class. 770 // Give it the same access (private/protected/public) as the script declared for the constructor.
852 * Give it the same access (private/protected/public) as the script declared for the constructor. 771 // Note that the reducer made sure there is at least a default constructor for every class.
853 * Note that the reducer made sure there is at least a default constructor for every class.
854 */
855 if(numFilled >= sdtClass.numVirtFuncs) 772 if(numFilled >= sdtClass.numVirtFuncs)
856 { 773 {
857 List<TokenDeclVar> newobjDeclFuncs = new List<TokenDeclVar>(); 774 List<TokenDeclVar> newobjDeclFuncs = new List<TokenDeclVar>();
@@ -870,9 +787,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
870 } 787 }
871 } 788 }
872 789
873 /* 790 // Write fixed portion of object file.
874 * Write fixed portion of object file.
875 */
876 objFileWriter.Write(OBJECT_CODE_MAGIC.ToCharArray()); 791 objFileWriter.Write(OBJECT_CODE_MAGIC.ToCharArray());
877 objFileWriter.Write(COMPILED_VERSION_VALUE); 792 objFileWriter.Write(COMPILED_VERSION_VALUE);
878 objFileWriter.Write(sourceHash); 793 objFileWriter.Write(sourceHash);
@@ -884,9 +799,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
884 objFileWriter.Write(stateNames[i]); 799 objFileWriter.Write(stateNames[i]);
885 } 800 }
886 801
887 /* 802 // For debugging, we also write out global variable array slot assignments.
888 * For debugging, we also write out global variable array slot assignments.
889 */
890 foreach(TokenDeclVar declVar in tokenScript.variablesStack) 803 foreach(TokenDeclVar declVar in tokenScript.variablesStack)
891 { 804 {
892 if(declVar.retType == null) 805 if(declVar.retType == null)
@@ -909,9 +822,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
909 } 822 }
910 objFileWriter.Write(""); 823 objFileWriter.Write("");
911 824
912 /* 825 // Write out script-defined types.
913 * Write out script-defined types.
914 */
915 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) 826 foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues)
916 { 827 {
917 objFileWriter.Write(sdType.longName.val); 828 objFileWriter.Write(sdType.longName.val);
@@ -919,13 +830,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
919 } 830 }
920 objFileWriter.Write(""); 831 objFileWriter.Write("");
921 832
922 /* 833 // Output function headers then bodies.
923 * Output function headers then bodies. 834 // Do all headers first in case bodies do forward references.
924 * Do all headers first in case bodies do forward references. 835 // Do both global functions, script-defined class static methods and
925 * Do both global functions, script-defined class static methods and 836 // script-defined instance methods, as we handle the differences
926 * script-defined instance methods, as we handle the differences 837 // during compilation of the functions/methods themselves.
927 * during compilation of the functions/methods themselves.
928 */
929 for(int pass = 0; pass < 2; pass++) 838 for(int pass = 0; pass < 2; pass++)
930 { 839 {
931 foreach(TokenDeclVar declFunc in tokenScript.variablesStack) 840 foreach(TokenDeclVar declFunc in tokenScript.variablesStack)
@@ -957,11 +866,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
957 } 866 }
958 } 867 }
959 868
960 /* 869 // Output default state event handler functions.
961 * Output default state event handler functions. 870 // Each event handler is a private static method named 'default <eventname>'.
962 * Each event handler is a private static method named 'default <eventname>'. 871 // Splice in a default state_entry() handler if none defined so we can init global vars.
963 * Splice in a default state_entry() handler if none defined so we can init global vars.
964 */
965 TokenDeclVar defaultStateEntry = null; 872 TokenDeclVar defaultStateEntry = null;
966 for(defaultStateEntry = tokenScript.defaultState.body.eventFuncs; 873 for(defaultStateEntry = tokenScript.defaultState.body.eventFuncs;
967 defaultStateEntry != null; 874 defaultStateEntry != null;
@@ -984,10 +891,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
984 } 891 }
985 GenerateStateEventHandlers("default", tokenScript.defaultState.body); 892 GenerateStateEventHandlers("default", tokenScript.defaultState.body);
986 893
987 /* 894 // Output script-defined state event handler methods.
988 * Output script-defined state event handler methods. 895 // Each event handler is a private static method named <statename> <eventname>
989 * Each event handler is a private static method named <statename> <eventname>
990 */
991 foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states) 896 foreach(KeyValuePair<string, TokenDeclState> kvp in tokenScript.states)
992 { 897 {
993 TokenDeclState declState = kvp.Value; 898 TokenDeclState declState = kvp.Value;
@@ -1059,13 +964,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1059 string eventname = declFunc.GetSimpleName(); 964 string eventname = declFunc.GetSimpleName();
1060 TokenArgDecl argDecl = declFunc.argDecl; 965 TokenArgDecl argDecl = declFunc.argDecl;
1061 966
1062 /* 967 // Make sure event handler name is valid and that number and type of arguments is correct.
1063 * Make sure event handler name is valid and that number and type of arguments is correct. 968 // Apparently some scripts exist with fewer than correct number of args in their declaration
1064 * Apparently some scripts exist with fewer than correct number of args in their declaration 969 // so allow for that. It is ok because the handlers are called with the arguments in an
1065 * so allow for that. It is ok because the handlers are called with the arguments in an 970 // object[] array, and we just won't access the missing argments in the vector. But the
1066 * object[] array, and we just won't access the missing argments in the vector. But the 971 // specified types must match one of the prototypes in legalEventHandlers.
1067 * specified types must match one of the prototypes in legalEventHandlers.
1068 */
1069 TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types); 972 TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types);
1070 if(protoDeclFunc == null) 973 if(protoDeclFunc == null)
1071 { 974 {
@@ -1073,10 +976,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1073 return; 976 return;
1074 } 977 }
1075 978
1076 /* 979 // Output function header.
1077 * Output function header. 980 // They just have the XMRInstAbstract pointer as the one argument.
1078 * They just have the XMRInstAbstract pointer as the one argument.
1079 */
1080 string functionName = statename + " " + eventname; 981 string functionName = statename + " " + eventname;
1081 _ilGen = new ScriptObjWriter(tokenScript, 982 _ilGen = new ScriptObjWriter(tokenScript,
1082 functionName, 983 functionName,
@@ -1086,34 +987,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1086 objFileWriter); 987 objFileWriter);
1087 StartFunctionBody(declFunc); 988 StartFunctionBody(declFunc);
1088 989
1089 /* 990 // Create a temp to hold XMRInstanceSuperType version of arg 0.
1090 * Create a temp to hold XMRInstanceSuperType version of arg 0.
1091 */
1092 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); 991 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst");
1093 ilGen.Emit(declFunc, OpCodes.Ldarg_0); 992 ilGen.Emit(declFunc, OpCodes.Ldarg_0);
1094 ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); 993 ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType);
1095 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); 994 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer);
1096 995
1097 /* 996 // Output args as variable definitions and initialize each from __sw.ehArgs[].
1098 * Output args as variable definitions and initialize each from __sw.ehArgs[]. 997 // If the script writer goofed, the typecast will complain.
1099 * If the script writer goofed, the typecast will complain.
1100 */
1101 int nArgs = argDecl.vars.Length; 998 int nArgs = argDecl.vars.Length;
1102 for(int i = 0; i < nArgs; i++) 999 for(int i = 0; i < nArgs; i++)
1103 { 1000 {
1104 1001 // Say that the argument variable is going to be located in a local var.
1105 /*
1106 * Say that the argument variable is going to be located in a local var.
1107 */
1108 TokenDeclVar argVar = argDecl.vars[i]; 1002 TokenDeclVar argVar = argDecl.vars[i];
1109 TokenType argTokType = argVar.type; 1003 TokenType argTokType = argVar.type;
1110 CompValuLocalVar local = new CompValuLocalVar(argTokType, argVar.name.val, this); 1004 CompValuLocalVar local = new CompValuLocalVar(argTokType, argVar.name.val, this);
1111 argVar.location = local; 1005 argVar.location = local;
1112 1006
1113 /* 1007 // Copy from the ehArgs[i] element to the temp var.
1114 * Copy from the ehArgs[i] element to the temp var. 1008 // Cast as needed, there is a lot of craziness like OpenMetaverse.Quaternion.
1115 * Cast as needed, there is a lot of craziness like OpenMetaverse.Quaternion.
1116 */
1117 local.PopPre(this, argVar.name); 1009 local.PopPre(this, argVar.name);
1118 PushXMRInst(); // instance 1010 PushXMRInst(); // instance
1119 ilGen.Emit(declFunc, OpCodes.Ldfld, ehArgsFieldInfo); // instance.ehArgs (array of objects) 1011 ilGen.Emit(declFunc, OpCodes.Ldfld, ehArgsFieldInfo); // instance.ehArgs (array of objects)
@@ -1154,9 +1046,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1154 local.PopPost(this, argVar.name, stkTokType); // pop stack type into argtype 1046 local.PopPost(this, argVar.name, stkTokType); // pop stack type into argtype
1155 } 1047 }
1156 1048
1157 /* 1049 // Output code for the statements and clean up.
1158 * Output code for the statements and clean up.
1159 */
1160 GenerateFuncBody(); 1050 GenerateFuncBody();
1161 } 1051 }
1162 1052
@@ -1168,12 +1058,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1168 { 1058 {
1169 curDeclFunc = declFunc; 1059 curDeclFunc = declFunc;
1170 1060
1171 /* 1061 // Make up array of all argument types as seen by the code generator.
1172 * Make up array of all argument types as seen by the code generator. 1062 // We splice in XMRInstanceSuperType or XMRSDTypeClObj for the first
1173 * We splice in XMRInstanceSuperType or XMRSDTypeClObj for the first 1063 // arg as the function itself is static, followed by script-visible
1174 * arg as the function itself is static, followed by script-visible 1064 // arg types.
1175 * arg types.
1176 */
1177 TokenArgDecl argDecl = declFunc.argDecl; 1065 TokenArgDecl argDecl = declFunc.argDecl;
1178 int nArgs = argDecl.vars.Length; 1066 int nArgs = argDecl.vars.Length;
1179 Type[] argTypes = new Type[nArgs + 1]; 1067 Type[] argTypes = new Type[nArgs + 1];
@@ -1194,9 +1082,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1194 argNames[i + 1] = argDecl.vars[i].name.val; 1082 argNames[i + 1] = argDecl.vars[i].name.val;
1195 } 1083 }
1196 1084
1197 /* 1085 // Set up entrypoint.
1198 * Set up entrypoint.
1199 */
1200 string objCodeName = declFunc.GetObjCodeName(); 1086 string objCodeName = declFunc.GetObjCodeName();
1201 declFunc.ilGen = new ScriptObjWriter(tokenScript, 1087 declFunc.ilGen = new ScriptObjWriter(tokenScript,
1202 objCodeName, 1088 objCodeName,
@@ -1205,9 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1205 argNames, 1091 argNames,
1206 objFileWriter); 1092 objFileWriter);
1207 1093
1208 /* 1094 // This says how to generate a call to the function and to get a delegate.
1209 * This says how to generate a call to the function and to get a delegate.
1210 */
1211 declFunc.location = new CompValuGlobalMeth(declFunc); 1095 declFunc.location = new CompValuGlobalMeth(declFunc);
1212 1096
1213 curDeclFunc = null; 1097 curDeclFunc = null;
@@ -1221,20 +1105,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1221 */ 1105 */
1222 private void GenerateMethodBody(TokenDeclVar declFunc) 1106 private void GenerateMethodBody(TokenDeclVar declFunc)
1223 { 1107 {
1224 /* 1108 // Set up code generator for the function's contents.
1225 * Set up code generator for the function's contents.
1226 */
1227 _ilGen = declFunc.ilGen; 1109 _ilGen = declFunc.ilGen;
1228 StartFunctionBody(declFunc); 1110 StartFunctionBody(declFunc);
1229 1111
1230 /* 1112 // Create a temp to hold XMRInstanceSuperType version of arg 0.
1231 * Create a temp to hold XMRInstanceSuperType version of arg 0. 1113 // For most functions, arg 0 is already XMRInstanceSuperType.
1232 * For most functions, arg 0 is already XMRInstanceSuperType. 1114 // But for script-defined class instance methods, arg 0 holds
1233 * But for script-defined class instance methods, arg 0 holds 1115 // the XMRSDTypeClObj pointer and so we read the XMRInstAbstract
1234 * the XMRSDTypeClObj pointer and so we read the XMRInstAbstract 1116 // pointer from its XMRSDTypeClObj.xmrInst field then cast it to
1235 * pointer from its XMRSDTypeClObj.xmrInst field then cast it to 1117 // XMRInstanceSuperType.
1236 * XMRInstanceSuperType.
1237 */
1238 if(IsSDTInstMethod()) 1118 if(IsSDTInstMethod())
1239 { 1119 {
1240 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); 1120 instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst");
@@ -1244,11 +1124,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1244 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); 1124 ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer);
1245 } 1125 }
1246 1126
1247 /* 1127 // Define location of all script-level arguments so script body can access them.
1248 * Define location of all script-level arguments so script body can access them. 1128 // The argument indices need to have +1 added to them because XMRInstance or
1249 * The argument indices need to have +1 added to them because XMRInstance or 1129 // XMRSDTypeClObj is spliced in at arg 0.
1250 * XMRSDTypeClObj is spliced in at arg 0.
1251 */
1252 TokenArgDecl argDecl = declFunc.argDecl; 1130 TokenArgDecl argDecl = declFunc.argDecl;
1253 int nArgs = argDecl.vars.Length; 1131 int nArgs = argDecl.vars.Length;
1254 for(int i = 0; i < nArgs; i++) 1132 for(int i = 0; i < nArgs; i++)
@@ -1257,27 +1135,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1257 argVar.location = new CompValuArg(argVar.type, i + 1); 1135 argVar.location = new CompValuArg(argVar.type, i + 1);
1258 } 1136 }
1259 1137
1260 /* 1138 // Output code for the statements and clean up.
1261 * Output code for the statements and clean up.
1262 */
1263 GenerateFuncBody(); 1139 GenerateFuncBody();
1264 } 1140 }
1265 1141
1266 private void StartFunctionBody(TokenDeclVar declFunc) 1142 private void StartFunctionBody(TokenDeclVar declFunc)
1267 { 1143 {
1268 /* 1144 // Start current function being processed.
1269 * Start current function being processed. 1145 // Set 'mightGetHere' as the code at the top is always executed.
1270 * Set 'mightGetHere' as the code at the top is always executed.
1271 */
1272 instancePointer = null; 1146 instancePointer = null;
1273 mightGetHere = true; 1147 mightGetHere = true;
1274 curBreakTarg = null; 1148 curBreakTarg = null;
1275 curContTarg = null; 1149 curContTarg = null;
1276 curDeclFunc = declFunc; 1150 curDeclFunc = declFunc;
1277 1151
1278 /* 1152 // Start generating code.
1279 * Start generating code.
1280 */
1281 ((ScriptObjWriter)ilGen).BegMethod(); 1153 ((ScriptObjWriter)ilGen).BegMethod();
1282 } 1154 }
1283 1155
@@ -1287,9 +1159,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1287 */ 1159 */
1288 private TokenDeclVar DefineNewobjFunc(TokenDeclVar ctorDeclFunc) 1160 private TokenDeclVar DefineNewobjFunc(TokenDeclVar ctorDeclFunc)
1289 { 1161 {
1290 /* 1162 // Set up 'static classname $new(params-same-as-ctor) { }'.
1291 * Set up 'static classname $new(params-same-as-ctor) { }'.
1292 */
1293 TokenDeclVar newobjDeclFunc = new TokenDeclVar(ctorDeclFunc, null, tokenScript); 1163 TokenDeclVar newobjDeclFunc = new TokenDeclVar(ctorDeclFunc, null, tokenScript);
1294 newobjDeclFunc.name = new TokenName(newobjDeclFunc, "$new"); 1164 newobjDeclFunc.name = new TokenName(newobjDeclFunc, "$new");
1295 newobjDeclFunc.retType = ctorDeclFunc.sdtClass.MakeRefToken(newobjDeclFunc); 1165 newobjDeclFunc.retType = ctorDeclFunc.sdtClass.MakeRefToken(newobjDeclFunc);
@@ -1297,10 +1167,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1297 newobjDeclFunc.sdtClass = ctorDeclFunc.sdtClass; 1167 newobjDeclFunc.sdtClass = ctorDeclFunc.sdtClass;
1298 newobjDeclFunc.sdtFlags = ScriptReduce.SDT_STATIC | ctorDeclFunc.sdtFlags; 1168 newobjDeclFunc.sdtFlags = ScriptReduce.SDT_STATIC | ctorDeclFunc.sdtFlags;
1299 1169
1300 /* 1170 // Declare local variable named '$objptr' in a frame just under
1301 * Declare local variable named '$objptr' in a frame just under 1171 // what the '$new(...)' function's arguments are declared in.
1302 * what the '$new(...)' function's arguments are declared in.
1303 */
1304 TokenDeclVar objptrVar = new TokenDeclVar(newobjDeclFunc, newobjDeclFunc, tokenScript); 1172 TokenDeclVar objptrVar = new TokenDeclVar(newobjDeclFunc, newobjDeclFunc, tokenScript);
1305 objptrVar.type = newobjDeclFunc.retType; 1173 objptrVar.type = newobjDeclFunc.retType;
1306 objptrVar.name = new TokenName(newobjDeclFunc, "$objptr"); 1174 objptrVar.name = new TokenName(newobjDeclFunc, "$objptr");
@@ -1308,20 +1176,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1308 newFrame.outerVarDict = ctorDeclFunc.argDecl.varDict; 1176 newFrame.outerVarDict = ctorDeclFunc.argDecl.varDict;
1309 newFrame.AddEntry(objptrVar); 1177 newFrame.AddEntry(objptrVar);
1310 1178
1311 /* 1179 // Set up '$objptr.$ctor'
1312 * Set up '$objptr.$ctor'
1313 */
1314 TokenLValName objptrLValName = new TokenLValName(objptrVar.name, newFrame); 1180 TokenLValName objptrLValName = new TokenLValName(objptrVar.name, newFrame);
1181
1315 // ref a var by giving its name 1182 // ref a var by giving its name
1316 TokenLValIField objptrDotCtor = new TokenLValIField(newobjDeclFunc); // an instance member reference 1183 TokenLValIField objptrDotCtor = new TokenLValIField(newobjDeclFunc); // an instance member reference
1317 objptrDotCtor.baseRVal = objptrLValName; // '$objptr' 1184 objptrDotCtor.baseRVal = objptrLValName; // '$objptr'
1318 objptrDotCtor.fieldName = ctorDeclFunc.name; // '.' '$ctor' 1185 objptrDotCtor.fieldName = ctorDeclFunc.name; // '.' '$ctor'
1319 1186
1320 /* 1187 // Set up '$objptr.$ctor(arglist)' call for use in the '$new(...)' body.
1321 * Set up '$objptr.$ctor(arglist)' call for use in the '$new(...)' body. 1188 // Copy the arglist from the constructor declaration so triviality
1322 * Copy the arglist from the constructor declaration so triviality 1189 // processing will pick the correct overloaded constructor.
1323 * processing will pick the correct overloaded constructor.
1324 */
1325 TokenRValCall callCtorRVal = new TokenRValCall(newobjDeclFunc); // doing a call of some sort 1190 TokenRValCall callCtorRVal = new TokenRValCall(newobjDeclFunc); // doing a call of some sort
1326 callCtorRVal.meth = objptrDotCtor; // calling $objptr.$ctor() 1191 callCtorRVal.meth = objptrDotCtor; // calling $objptr.$ctor()
1327 TokenDeclVar[] argList = newobjDeclFunc.argDecl.vars; // get args $new() was declared with 1192 TokenDeclVar[] argList = newobjDeclFunc.argDecl.vars; // get args $new() was declared with
@@ -1335,32 +1200,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1335 callCtorRVal.args = argLValName; 1200 callCtorRVal.args = argLValName;
1336 } 1201 }
1337 1202
1338 /* 1203 // Set up a funky call to the constructor for the code body.
1339 * Set up a funky call to the constructor for the code body. 1204 // This will let code generator know there is some craziness.
1340 * This will let code generator know there is some craziness. 1205 // See GenerateStmtNewobj().
1341 * See GenerateStmtNewobj(). 1206 //
1342 * 1207 // This is in essence:
1343 * This is in essence: 1208 // {
1344 * { 1209 // classname $objptr = newobj (classname);
1345 * classname $objptr = newobj (classname); 1210 // $objptr.$ctor (...);
1346 * $objptr.$ctor (...); 1211 // return $objptr;
1347 * return $objptr; 1212 // }
1348 * }
1349 */
1350 TokenStmtNewobj newobjStmtBody = new TokenStmtNewobj(ctorDeclFunc); 1213 TokenStmtNewobj newobjStmtBody = new TokenStmtNewobj(ctorDeclFunc);
1351 newobjStmtBody.objptrVar = objptrVar; 1214 newobjStmtBody.objptrVar = objptrVar;
1352 newobjStmtBody.rValCall = callCtorRVal; 1215 newobjStmtBody.rValCall = callCtorRVal;
1353 TokenStmtBlock newobjBody = new TokenStmtBlock(ctorDeclFunc); 1216 TokenStmtBlock newobjBody = new TokenStmtBlock(ctorDeclFunc);
1354 newobjBody.statements = newobjStmtBody; 1217 newobjBody.statements = newobjStmtBody;
1355 1218
1356 /* 1219 // Link that code as the body of the function.
1357 * Link that code as the body of the function.
1358 */
1359 newobjDeclFunc.body = newobjBody; 1220 newobjDeclFunc.body = newobjBody;
1360 1221
1361 /* 1222 // Say the function calls '$objptr.$ctor(arglist)' so we will inherit ctor's triviality.
1362 * Say the function calls '$objptr.$ctor(arglist)' so we will inherit ctor's triviality.
1363 */
1364 newobjDeclFunc.unknownTrivialityCalls.AddLast(callCtorRVal); 1223 newobjDeclFunc.unknownTrivialityCalls.AddLast(callCtorRVal);
1365 return newobjDeclFunc; 1224 return newobjDeclFunc;
1366 } 1225 }
@@ -1377,43 +1236,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1377 */ 1236 */
1378 private void GenerateFuncBody() 1237 private void GenerateFuncBody()
1379 { 1238 {
1380 /* 1239 // We want to know if the function's code is trivial, ie,
1381 * We want to know if the function's code is trivial, ie, 1240 // if it doesn't have anything that might be an infinite
1382 * if it doesn't have anything that might be an infinite 1241 // loop and that is doesn't call anything that might have
1383 * loop and that is doesn't call anything that might have 1242 // an infinite loop. If it is, we don't need any CheckRun()
1384 * an infinite loop. If it is, we don't need any CheckRun() 1243 // stuff or any of the frame save/restore stuff.
1385 * stuff or any of the frame save/restore stuff.
1386 */
1387 bool isTrivial = curDeclFunc.IsFuncTrivial(this); 1244 bool isTrivial = curDeclFunc.IsFuncTrivial(this);
1388 1245
1389 /* 1246 // Clear list of all call labels.
1390 * Clear list of all call labels. 1247 // A call label is inserted just before every call that can possibly
1391 * A call label is inserted just before every call that can possibly 1248 // call CheckRun(), including any direct calls to CheckRun().
1392 * call CheckRun(), including any direct calls to CheckRun(). 1249 // Then, when restoring stack, we can just switch to this label to
1393 * Then, when restoring stack, we can just switch to this label to 1250 // resume at the correct spot.
1394 * resume at the correct spot.
1395 */
1396 actCallLabels.Clear(); 1251 actCallLabels.Clear();
1397 allCallLabels.Clear(); 1252 allCallLabels.Clear();
1398 openCallLabel = null; 1253 openCallLabel = null;
1399 1254
1400 /* 1255 // Alloc stack space for local vars.
1401 * Alloc stack space for local vars.
1402 */
1403 int stackframesize = AllocLocalVarStackSpace(); 1256 int stackframesize = AllocLocalVarStackSpace();
1404 1257
1405 /* 1258 // Include argument variables in stack space for this frame.
1406 * Include argument variables in stack space for this frame.
1407 */
1408 foreach(TokenType tokType in curDeclFunc.argDecl.types) 1259 foreach(TokenType tokType in curDeclFunc.argDecl.types)
1409 { 1260 {
1410 stackframesize += LocalVarStackSize(tokType); 1261 stackframesize += LocalVarStackSize(tokType);
1411 } 1262 }
1412 1263
1413 /* 1264 // Any return statements inside function body jump to this label
1414 * Any return statements inside function body jump to this label 1265 // after putting return value in __retval.
1415 * after putting return value in __retval.
1416 */
1417 retLabel = ilGen.DefineLabel("__retlbl"); 1266 retLabel = ilGen.DefineLabel("__retlbl");
1418 retValue = null; 1267 retValue = null;
1419 if(!(curDeclFunc.retType is TokenTypeVoid)) 1268 if(!(curDeclFunc.retType is TokenTypeVoid))
@@ -1421,13 +1270,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1421 retValue = ilGen.DeclareLocal(curDeclFunc.retType.ToSysType(), "__retval"); 1270 retValue = ilGen.DeclareLocal(curDeclFunc.retType.ToSysType(), "__retval");
1422 } 1271 }
1423 1272
1424 /* 1273 // Output:
1425 * Output: 1274 // int __mainCallNo = -1;
1426 * int __mainCallNo = -1; 1275 // instance.m_StackLeft -= stackframesize;
1427 * instance.m_StackLeft -= stackframesize; 1276 // try {
1428 * try { 1277 // if (instance.callMode != CallMode_NORMAL) goto __cmRestore;
1429 * if (instance.callMode != CallMode_NORMAL) goto __cmRestore;
1430 */
1431 actCallNo = null; 1278 actCallNo = null;
1432 ScriptMyLabel cmRestore = null; 1279 ScriptMyLabel cmRestore = null;
1433 if(!isTrivial) 1280 if(!isTrivial)
@@ -1448,18 +1295,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1448 ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, cmRestore); 1295 ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, cmRestore);
1449 } 1296 }
1450 1297
1451 /* 1298 // Splice in the code optimizer for the body of the function.
1452 * Splice in the code optimizer for the body of the function.
1453 */
1454 ScriptCollector collector = new ScriptCollector((ScriptObjWriter)ilGen); 1299 ScriptCollector collector = new ScriptCollector((ScriptObjWriter)ilGen);
1455 _ilGen = collector; 1300 _ilGen = collector;
1456 1301
1457 /* 1302 // If this is the default state_entry() handler, output code to set all global
1458 * If this is the default state_entry() handler, output code to set all global 1303 // variables to their initial values. Note that every script must have a
1459 * variables to their initial values. Note that every script must have a 1304 // default state_entry() handler, we provide one if the script doesn't explicitly
1460 * default state_entry() handler, we provide one if the script doesn't explicitly 1305 // define one.
1461 * define one.
1462 */
1463 string methname = ilGen.methName; 1306 string methname = ilGen.methName;
1464 if(methname == "default state_entry") 1307 if(methname == "default state_entry")
1465 { 1308 {
@@ -1501,10 +1344,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1501 ilGen.MarkLabel(skipGblInitLabel); 1344 ilGen.MarkLabel(skipGblInitLabel);
1502 } 1345 }
1503 1346
1504 /* 1347 // If this is a script-defined type constructor, call the base constructor and call
1505 * If this is a script-defined type constructor, call the base constructor and call 1348 // this class's $instfieldinit() method to initialize instance fields.
1506 * this class's $instfieldinit() method to initialize instance fields.
1507 */
1508 if((curDeclFunc.sdtClass != null) && curDeclFunc.funcNameSig.val.StartsWith("$ctor(")) 1349 if((curDeclFunc.sdtClass != null) && curDeclFunc.funcNameSig.val.StartsWith("$ctor("))
1509 { 1350 {
1510 if(curDeclFunc.baseCtorCall != null) 1351 if(curDeclFunc.baseCtorCall != null)
@@ -1521,22 +1362,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1521 } 1362 }
1522 } 1363 }
1523 1364
1524 /* 1365 // See if time to suspend in case they are doing a loop with recursion.
1525 * See if time to suspend in case they are doing a loop with recursion.
1526 */
1527 if(!isTrivial) 1366 if(!isTrivial)
1528 EmitCallCheckRun(curDeclFunc, true); 1367 EmitCallCheckRun(curDeclFunc, true);
1529 1368
1530 /* 1369 // Output code body.
1531 * Output code body.
1532 */
1533 GenerateStmtBlock(curDeclFunc.body); 1370 GenerateStmtBlock(curDeclFunc.body);
1534 1371
1535 /* 1372 // If code falls through to this point, means they are missing
1536 * If code falls through to this point, means they are missing 1373 // a return statement. And that is legal only if the function
1537 * a return statement. And that is legal only if the function 1374 // returns 'void'.
1538 * returns 'void'.
1539 */
1540 if(mightGetHere) 1375 if(mightGetHere)
1541 { 1376 {
1542 if(!(curDeclFunc.retType is TokenTypeVoid)) 1377 if(!(curDeclFunc.retType is TokenTypeVoid))
@@ -1546,28 +1381,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1546 ilGen.Emit(curDeclFunc, OpCodes.Leave, retLabel); 1381 ilGen.Emit(curDeclFunc, OpCodes.Leave, retLabel);
1547 } 1382 }
1548 1383
1549 /* 1384 // End of the code to be optimized.
1550 * End of the code to be optimized. 1385 // Do optimizations then write it all out to object file.
1551 * Do optimizations then write it all out to object file. 1386 // After this, all code gets written directly to object file.
1552 * After this, all code gets written directly to object file. 1387 // Optimization must be completed before we scan the allCallLabels
1553 * Optimization must be completed before we scan the allCallLabels 1388 // list below to look for active locals and temps.
1554 * list below to look for active locals and temps.
1555 */
1556 collector.Optimize(); 1389 collector.Optimize();
1557 _ilGen = collector.WriteOutAll(); 1390 _ilGen = collector.WriteOutAll();
1558 collector = null; 1391 collector = null;
1559 1392
1560 /* 1393 // Output code to restore stack frame from stream.
1561 * Output code to restore stack frame from stream. 1394 // It jumps back to the call labels within the function body.
1562 * It jumps back to the call labels within the function body.
1563 */
1564 List<ScriptMyLocal> activeTemps = null; 1395 List<ScriptMyLocal> activeTemps = null;
1565 if(!isTrivial) 1396 if(!isTrivial)
1566 { 1397 {
1567 1398 // Build list of locals and temps active at all the call labels.
1568 /*
1569 * Build list of locals and temps active at all the call labels.
1570 */
1571 activeTemps = new List<ScriptMyLocal>(); 1399 activeTemps = new List<ScriptMyLocal>();
1572 foreach(CallLabel cl in allCallLabels) 1400 foreach(CallLabel cl in allCallLabels)
1573 { 1401 {
@@ -1580,24 +1408,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1580 } 1408 }
1581 } 1409 }
1582 1410
1583 /* 1411 // Output code to restore the args, locals and temps then jump to
1584 * Output code to restore the args, locals and temps then jump to 1412 // the call label that we were interrupted at.
1585 * the call label that we were interrupted at.
1586 */
1587 ilGen.MarkLabel(cmRestore); 1413 ilGen.MarkLabel(cmRestore);
1588 GenerateFrameRestoreCode(activeTemps); 1414 GenerateFrameRestoreCode(activeTemps);
1589 } 1415 }
1590 1416
1591 /* 1417 // Output epilog that saves stack frame state if CallMode_SAVE.
1592 * Output epilog that saves stack frame state if CallMode_SAVE. 1418 //
1593 * 1419 // finally {
1594 * finally { 1420 // instance.m_StackLeft += stackframesize;
1595 * instance.m_StackLeft += stackframesize; 1421 // if (instance.callMode != CallMode_SAVE) goto __endFin;
1596 * if (instance.callMode != CallMode_SAVE) goto __endFin; 1422 // GenerateFrameCaptureCode();
1597 * GenerateFrameCaptureCode(); 1423 // __endFin:
1598 * __endFin: 1424 // }
1599 * }
1600 */
1601 ScriptMyLabel endFin = null; 1425 ScriptMyLabel endFin = null;
1602 if(!isTrivial) 1426 if(!isTrivial)
1603 { 1427 {
@@ -1619,9 +1443,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1619 ilGen.EndExceptionBlock(); 1443 ilGen.EndExceptionBlock();
1620 } 1444 }
1621 1445
1622 /* 1446 // Output the 'real' return opcode.
1623 * Output the 'real' return opcode.
1624 */
1625 ilGen.MarkLabel(retLabel); 1447 ilGen.MarkLabel(retLabel);
1626 if(!(curDeclFunc.retType is TokenTypeVoid)) 1448 if(!(curDeclFunc.retType is TokenTypeVoid))
1627 { 1449 {
@@ -1631,15 +1453,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1631 retLabel = null; 1453 retLabel = null;
1632 retValue = null; 1454 retValue = null;
1633 1455
1634 /* 1456 // No more instructions for this method.
1635 * No more instructions for this method.
1636 */
1637 ((ScriptObjWriter)ilGen).EndMethod(); 1457 ((ScriptObjWriter)ilGen).EndMethod();
1638 _ilGen = null; 1458 _ilGen = null;
1639 1459
1640 /* 1460 // Not generating function code any more.
1641 * Not generating function code any more.
1642 */
1643 curBreakTarg = null; 1461 curBreakTarg = null;
1644 curContTarg = null; 1462 curContTarg = null;
1645 curDeclFunc = null; 1463 curDeclFunc = null;
@@ -1655,21 +1473,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1655 int stackframesize = 64; // RIP, RBX, RBP, R12..R15, one extra 1473 int stackframesize = 64; // RIP, RBX, RBP, R12..R15, one extra
1656 foreach(TokenDeclVar localVar in curDeclFunc.localVars) 1474 foreach(TokenDeclVar localVar in curDeclFunc.localVars)
1657 { 1475 {
1658 1476 // Skip all 'constant' vars as they were handled by the reducer.
1659 /*
1660 * Skip all 'constant' vars as they were handled by the reducer.
1661 */
1662 if(localVar.constant) 1477 if(localVar.constant)
1663 continue; 1478 continue;
1664 1479
1665 /* 1480 // Get a stack location for the local variable.
1666 * Get a stack location for the local variable.
1667 */
1668 localVar.location = new CompValuLocalVar(localVar.type, localVar.name.val, this); 1481 localVar.location = new CompValuLocalVar(localVar.type, localVar.name.val, this);
1669 1482
1670 /* 1483 // Stack size for the local variable.
1671 * Stack size for the local variable.
1672 */
1673 stackframesize += LocalVarStackSize(localVar.type); 1484 stackframesize += LocalVarStackSize(localVar.type);
1674 } 1485 }
1675 return stackframesize; 1486 return stackframesize;
@@ -1692,17 +1503,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1692 */ 1503 */
1693 private void GenerateFrameCaptureCode(List<ScriptMyLocal> activeTemps) 1504 private void GenerateFrameCaptureCode(List<ScriptMyLocal> activeTemps)
1694 { 1505 {
1695 /* 1506 // Compute total number of slots we need to save stuff.
1696 * Compute total number of slots we need to save stuff. 1507 // Assume we need to save all call arguments.
1697 * Assume we need to save all call arguments.
1698 */
1699 int nSaves = curDeclFunc.argDecl.vars.Length + activeTemps.Count; 1508 int nSaves = curDeclFunc.argDecl.vars.Length + activeTemps.Count;
1700 1509
1701 /* 1510 // Output code to allocate a stack frame object with an object array.
1702 * Output code to allocate a stack frame object with an object array. 1511 // This also pushes the stack frame object on the instance.stackFrames list.
1703 * This also pushes the stack frame object on the instance.stackFrames list. 1512 // It returns a pointer to the object array it allocated.
1704 * It returns a pointer to the object array it allocated.
1705 */
1706 PushXMRInst(); 1513 PushXMRInst();
1707 ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); 1514 ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName);
1708 GetCallNo(curDeclFunc, actCallNo); 1515 GetCallNo(curDeclFunc, actCallNo);
@@ -1718,9 +1525,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1718 ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); 1525 ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo);
1719 } 1526 }
1720 1527
1721 /* 1528 // Copy arg values to object array, boxing as needed.
1722 * Copy arg values to object array, boxing as needed.
1723 */
1724 int i = 0; 1529 int i = 0;
1725 foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) 1530 foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict)
1726 { 1531 {
@@ -1738,9 +1543,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1738 i++; 1543 i++;
1739 } 1544 }
1740 1545
1741 /* 1546 // Copy local and temp values to object array, boxing as needed.
1742 * Copy local and temp values to object array, boxing as needed.
1743 */
1744 foreach(ScriptMyLocal lcl in activeTemps) 1547 foreach(ScriptMyLocal lcl in activeTemps)
1745 { 1548 {
1746 ilGen.Emit(curDeclFunc, OpCodes.Dup); 1549 ilGen.Emit(curDeclFunc, OpCodes.Dup);
@@ -1789,10 +1592,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1789 { 1592 {
1790 ScriptMyLocal objArray = ilGen.DeclareLocal(typeof(object[]), "__restObjArray"); 1593 ScriptMyLocal objArray = ilGen.DeclareLocal(typeof(object[]), "__restObjArray");
1791 1594
1792 /* 1595 // Output code to pop stack frame from instance.stackFrames.
1793 * Output code to pop stack frame from instance.stackFrames. 1596 // It returns a pointer to the object array that contains values to be restored.
1794 * It returns a pointer to the object array that contains values to be restored.
1795 */
1796 PushXMRInst(); 1597 PushXMRInst();
1797 ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); 1598 ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName);
1798 ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo 1599 ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo
@@ -1807,11 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1807 ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); 1608 ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo);
1808 } 1609 }
1809 1610
1810 /* 1611 // Restore argument values from object array, unboxing as needed.
1811 * Restore argument values from object array, unboxing as needed. 1612 // Although the caller has restored them to what it called us with, it's possible that this
1812 * Although the caller has restored them to what it called us with, it's possible that this 1613 // function has modified them since, so we need to do our own restore.
1813 * function has modified them since, so we need to do our own restore.
1814 */
1815 int i = 0; 1614 int i = 0;
1816 foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) 1615 foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict)
1817 { 1616 {
@@ -1832,9 +1631,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1832 i++; 1631 i++;
1833 } 1632 }
1834 1633
1835 /* 1634 // Restore local and temp values from object array, unboxing as needed.
1836 * Restore local and temp values from object array, unboxing as needed.
1837 */
1838 foreach(ScriptMyLocal lcl in activeTemps) 1635 foreach(ScriptMyLocal lcl in activeTemps)
1839 { 1636 {
1840 Type t = lcl.type; 1637 Type t = lcl.type;
@@ -1952,10 +1749,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1952 this.index = scg.actCallLabels.Count; 1749 this.index = scg.actCallLabels.Count;
1953 string name = "__call_" + index + "_" + scg.allCallLabels.Count; 1750 string name = "__call_" + index + "_" + scg.allCallLabels.Count;
1954 1751
1955 /* 1752 // Make sure eval stack is empty because the frame capture/restore
1956 * Make sure eval stack is empty because the frame capture/restore 1753 // code expects such (restore switch stmt has an empty stack).
1957 * code expects such (restore switch stmt has an empty stack).
1958 */
1959 int depth = ((ScriptCollector)scg.ilGen).stackDepth.Count; 1754 int depth = ((ScriptCollector)scg.ilGen).stackDepth.Count;
1960 if(depth > 0) 1755 if(depth > 0)
1961 { 1756 {
@@ -1963,9 +1758,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1963 throw new Exception("call label stack depth " + depth + " at " + errorAt.SrcLoc); 1758 throw new Exception("call label stack depth " + depth + " at " + errorAt.SrcLoc);
1964 } 1759 }
1965 1760
1966 /* 1761 // Eval stack is empty so the restore code can handle it.
1967 * Eval stack is empty so the restore code can handle it.
1968 */
1969 this.index = scg.actCallLabels.Count; 1762 this.index = scg.actCallLabels.Count;
1970 scg.actCallLabels.AddLast(this); 1763 scg.actCallLabels.AddLast(this);
1971 scg.allCallLabels.AddLast(this); 1764 scg.allCallLabels.AddLast(this);
@@ -2094,23 +1887,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2094 if(!mightGetHere) 1887 if(!mightGetHere)
2095 return; 1888 return;
2096 1889
2097 /* 1890 // Push new current statement block pointer for anyone who cares.
2098 * Push new current statement block pointer for anyone who cares.
2099 */
2100 TokenStmtBlock oldStmtBlock = curStmtBlock; 1891 TokenStmtBlock oldStmtBlock = curStmtBlock;
2101 curStmtBlock = stmtBlock; 1892 curStmtBlock = stmtBlock;
2102 1893
2103 /* 1894 // Output the statements that make up the block.
2104 * Output the statements that make up the block.
2105 */
2106 for(Token t = stmtBlock.statements; t != null; t = t.nextToken) 1895 for(Token t = stmtBlock.statements; t != null; t = t.nextToken)
2107 { 1896 {
2108 GenerateStmt((TokenStmt)t); 1897 GenerateStmt((TokenStmt)t);
2109 } 1898 }
2110 1899
2111 /* 1900 // Pop the current statement block.
2112 * Pop the current statement block.
2113 */
2114 curStmtBlock = oldStmtBlock; 1901 curStmtBlock = oldStmtBlock;
2115 } 1902 }
2116 1903
@@ -2122,23 +1909,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2122 if(!mightGetHere) 1909 if(!mightGetHere)
2123 return; 1910 return;
2124 1911
2125 /* 1912 // Make sure we are in a breakable situation.
2126 * Make sure we are in a breakable situation.
2127 */
2128 if(curBreakTarg == null) 1913 if(curBreakTarg == null)
2129 { 1914 {
2130 ErrorMsg(breakStmt, "not in a breakable situation"); 1915 ErrorMsg(breakStmt, "not in a breakable situation");
2131 return; 1916 return;
2132 } 1917 }
2133 1918
2134 /* 1919 // Tell anyone who cares that the break target was actually used.
2135 * Tell anyone who cares that the break target was actually used.
2136 */
2137 curBreakTarg.used = true; 1920 curBreakTarg.used = true;
2138 1921
2139 /* 1922 // Output the instructions.
2140 * Output the instructions.
2141 */
2142 EmitJumpCode(curBreakTarg.label, curBreakTarg.block, breakStmt); 1923 EmitJumpCode(curBreakTarg.label, curBreakTarg.block, breakStmt);
2143 } 1924 }
2144 1925
@@ -2150,23 +1931,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2150 if(!mightGetHere) 1931 if(!mightGetHere)
2151 return; 1932 return;
2152 1933
2153 /* 1934 // Make sure we are in a contable situation.
2154 * Make sure we are in a contable situation.
2155 */
2156 if(curContTarg == null) 1935 if(curContTarg == null)
2157 { 1936 {
2158 ErrorMsg(contStmt, "not in a continueable situation"); 1937 ErrorMsg(contStmt, "not in a continueable situation");
2159 return; 1938 return;
2160 } 1939 }
2161 1940
2162 /* 1941 // Tell anyone who cares that the continue target was actually used.
2163 * Tell anyone who cares that the continue target was actually used.
2164 */
2165 curContTarg.used = true; 1942 curContTarg.used = true;
2166 1943
2167 /* 1944 // Output the instructions.
2168 * Output the instructions.
2169 */
2170 EmitJumpCode(curContTarg.label, curContTarg.block, contStmt); 1945 EmitJumpCode(curContTarg.label, curContTarg.block, contStmt);
2171 } 1946 }
2172 1947
@@ -2199,29 +1974,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2199 CompValu testRVal = GenerateFromRVal(doStmt.testRVal); 1974 CompValu testRVal = GenerateFromRVal(doStmt.testRVal);
2200 if(IsConstBoolExprTrue(testRVal)) 1975 if(IsConstBoolExprTrue(testRVal))
2201 { 1976 {
2202 1977 // Unconditional looping, unconditional branch and
2203 /* 1978 // say we never fall through to next statement.
2204 * Unconditional looping, unconditional branch and
2205 * say we never fall through to next statement.
2206 */
2207 ilGen.Emit(doStmt, OpCodes.Br, loopLabel); 1979 ilGen.Emit(doStmt, OpCodes.Br, loopLabel);
2208 mightGetHere = false; 1980 mightGetHere = false;
2209 } 1981 }
2210 else 1982 else
2211 { 1983 {
2212 1984 // Conditional looping, test and brach back to top of loop.
2213 /*
2214 * Conditional looping, test and brach back to top of loop.
2215 */
2216 testRVal.PushVal(this, doStmt.testRVal, tokenTypeBool); 1985 testRVal.PushVal(this, doStmt.testRVal, tokenTypeBool);
2217 ilGen.Emit(doStmt, OpCodes.Brtrue, loopLabel); 1986 ilGen.Emit(doStmt, OpCodes.Brtrue, loopLabel);
2218 } 1987 }
2219 } 1988 }
2220 1989
2221 /* 1990 // If 'break' statement was used, output target label.
2222 * If 'break' statement was used, output target label. 1991 // And assume that since a 'break' statement was used, it's possible for the code to get here.
2223 * And assume that since a 'break' statement was used, it's possible for the code to get here.
2224 */
2225 if(curBreakTarg.used) 1992 if(curBreakTarg.used)
2226 { 1993 {
2227 ilGen.MarkLabel(curBreakTarg.label); 1994 ilGen.MarkLabel(curBreakTarg.label);
@@ -2253,10 +2020,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2253 } 2020 }
2254 ilGen.MarkLabel(loopLabel); 2021 ilGen.MarkLabel(loopLabel);
2255 2022
2256 /* 2023 // See if we have a test expression that is other than a constant TRUE.
2257 * See if we have a test expression that is other than a constant TRUE. 2024 // If so, test it and conditionally branch to end if false.
2258 * If so, test it and conditionally branch to end if false.
2259 */
2260 if(forStmt.testRVal != null) 2025 if(forStmt.testRVal != null)
2261 { 2026 {
2262 CompValu testRVal = GenerateFromRVal(forStmt.testRVal); 2027 CompValu testRVal = GenerateFromRVal(forStmt.testRVal);
@@ -2268,14 +2033,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2268 } 2033 }
2269 } 2034 }
2270 2035
2271 /* 2036 // Output loop body.
2272 * Output loop body.
2273 */
2274 GenerateStmt(forStmt.bodyStmt); 2037 GenerateStmt(forStmt.bodyStmt);
2275 2038
2276 /* 2039 // Here's where a 'continue' statement jumps to.
2277 * Here's where a 'continue' statement jumps to.
2278 */
2279 if(curContTarg.used) 2040 if(curContTarg.used)
2280 { 2041 {
2281 ilGen.MarkLabel(curContTarg.label); 2042 ilGen.MarkLabel(curContTarg.label);
@@ -2284,27 +2045,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2284 2045
2285 if(mightGetHere) 2046 if(mightGetHere)
2286 { 2047 {
2287 2048 // After checking for excessive CPU time, output increment statement, if any.
2288 /*
2289 * After checking for excessive CPU time, output increment statement, if any.
2290 */
2291 EmitCallCheckRun(forStmt, false); 2049 EmitCallCheckRun(forStmt, false);
2292 if(forStmt.incrRVal != null) 2050 if(forStmt.incrRVal != null)
2293 { 2051 {
2294 GenerateFromRVal(forStmt.incrRVal); 2052 GenerateFromRVal(forStmt.incrRVal);
2295 } 2053 }
2296 2054
2297 /* 2055 // Unconditional branch back to beginning of loop.
2298 * Unconditional branch back to beginning of loop.
2299 */
2300 ilGen.Emit(forStmt, OpCodes.Br, loopLabel); 2056 ilGen.Emit(forStmt, OpCodes.Br, loopLabel);
2301 } 2057 }
2302 2058
2303 /* 2059 // If test needs label, output label for it to jump to.
2304 * If test needs label, output label for it to jump to. 2060 // Otherwise, clear mightGetHere as we know loop never
2305 * Otherwise, clear mightGetHere as we know loop never 2061 // falls out the bottom.
2306 * falls out the bottom.
2307 */
2308 mightGetHere = curBreakTarg.used; 2062 mightGetHere = curBreakTarg.used;
2309 if(mightGetHere) 2063 if(mightGetHere)
2310 { 2064 {
@@ -2433,16 +2187,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2433 2187
2434 bool constVal; 2188 bool constVal;
2435 2189
2436 /* 2190 // Test condition and see if constant test expression.
2437 * Test condition and see if constant test expression.
2438 */
2439 CompValu testRVal = GenerateFromRVal(ifStmt.testRVal); 2191 CompValu testRVal = GenerateFromRVal(ifStmt.testRVal);
2440 if(IsConstBoolExpr(testRVal, out constVal)) 2192 if(IsConstBoolExpr(testRVal, out constVal))
2441 { 2193 {
2442 2194 // Constant, output just either the true or else part.
2443 /*
2444 * Constant, output just either the true or else part.
2445 */
2446 if(constVal) 2195 if(constVal)
2447 { 2196 {
2448 GenerateStmt(ifStmt.trueStmt); 2197 GenerateStmt(ifStmt.trueStmt);
@@ -2454,10 +2203,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2454 } 2203 }
2455 else if(ifStmt.elseStmt == null) 2204 else if(ifStmt.elseStmt == null)
2456 { 2205 {
2457 2206 // This is an 'if' statement without an 'else' clause.
2458 /*
2459 * This is an 'if' statement without an 'else' clause.
2460 */
2461 testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); 2207 testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool);
2462 ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique); 2208 ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique);
2463 ilGen.Emit(ifStmt, OpCodes.Brfalse, doneLabel); // brfalse doneLabel 2209 ilGen.Emit(ifStmt, OpCodes.Brfalse, doneLabel); // brfalse doneLabel
@@ -2467,10 +2213,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2467 } 2213 }
2468 else 2214 else
2469 { 2215 {
2470 2216 // This is an 'if' statement with an 'else' clause.
2471 /*
2472 * This is an 'if' statement with an 'else' clause.
2473 */
2474 testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); 2217 testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool);
2475 ScriptMyLabel elseLabel = ilGen.DefineLabel("ifelse_" + ifStmt.Unique); 2218 ScriptMyLabel elseLabel = ilGen.DefineLabel("ifelse_" + ifStmt.Unique);
2476 ilGen.Emit(ifStmt, OpCodes.Brfalse, elseLabel); // brfalse elseLabel 2219 ilGen.Emit(ifStmt, OpCodes.Brfalse, elseLabel); // brfalse elseLabel
@@ -2494,9 +2237,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2494 if(!mightGetHere) 2237 if(!mightGetHere)
2495 return; 2238 return;
2496 2239
2497 /* 2240 // Make sure the target label is defined somewhere in the function.
2498 * Make sure the target label is defined somewhere in the function.
2499 */
2500 TokenStmtLabel stmtLabel; 2241 TokenStmtLabel stmtLabel;
2501 if(!curDeclFunc.labels.TryGetValue(jumpStmt.label.val, out stmtLabel)) 2242 if(!curDeclFunc.labels.TryGetValue(jumpStmt.label.val, out stmtLabel))
2502 { 2243 {
@@ -2509,9 +2250,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2509 stmtLabel.labelTagged = true; 2250 stmtLabel.labelTagged = true;
2510 } 2251 }
2511 2252
2512 /* 2253 // Emit instructions to do the jump.
2513 * Emit instructions to do the jump.
2514 */
2515 EmitJumpCode(stmtLabel.labelStruct, stmtLabel.block, jumpStmt); 2254 EmitJumpCode(stmtLabel.labelStruct, stmtLabel.block, jumpStmt);
2516 } 2255 }
2517 2256
@@ -2522,20 +2261,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2522 */ 2261 */
2523 private void EmitJumpCode(ScriptMyLabel target, TokenStmtBlock targetsBlock, Token errorAt) 2262 private void EmitJumpCode(ScriptMyLabel target, TokenStmtBlock targetsBlock, Token errorAt)
2524 { 2263 {
2525 /* 2264 // Jumps never fall through.
2526 * Jumps never fall through. 2265
2527 */
2528 mightGetHere = false; 2266 mightGetHere = false;
2529 2267
2530 /* 2268 // Find which block the target label is in. Must be in this or an outer block,
2531 * Find which block the target label is in. Must be in this or an outer block, 2269 // no laterals allowed. And if we exit a try/catch block, use Leave instead of Br.
2532 * no laterals allowed. And if we exit a try/catch block, use Leave instead of Br. 2270 //
2533 * 2271 // jump lateral;
2534 * jump lateral; 2272 // {
2535 * { 2273 // @lateral;
2536 * @lateral; 2274 // }
2537 * }
2538 */
2539 bool useLeave = false; 2275 bool useLeave = false;
2540 TokenStmtBlock stmtBlock; 2276 TokenStmtBlock stmtBlock;
2541 Stack<TokenStmtTry> finallyBlocksCalled = new Stack<TokenStmtTry>(); 2277 Stack<TokenStmtTry> finallyBlocksCalled = new Stack<TokenStmtTry>();
@@ -2559,46 +2295,44 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2559 } 2295 }
2560 } 2296 }
2561 2297
2562 /* 2298 // If popping through more than one finally block, we have to break it down for the stack
2563 * If popping through more than one finally block, we have to break it down for the stack 2299 // capture and restore code, one finally block at a time.
2564 * capture and restore code, one finally block at a time. 2300 //
2565 * 2301 // try {
2566 * try { 2302 // try {
2567 * try { 2303 // try {
2568 * try { 2304 // jump exit;
2569 * jump exit; 2305 // } finally {
2570 * } finally { 2306 // llOwnerSay ("exiting inner");
2571 * llOwnerSay ("exiting inner"); 2307 // }
2572 * } 2308 // } finally {
2573 * } finally { 2309 // llOwnerSay ("exiting middle");
2574 * llOwnerSay ("exiting middle"); 2310 // }
2575 * } 2311 // } finally {
2576 * } finally { 2312 // llOwnerSay ("exiting outer");
2577 * llOwnerSay ("exiting outer"); 2313 // }
2578 * } 2314 // @exit;
2579 * @exit; 2315 //
2580 * 2316 // try {
2581 * try { 2317 // try {
2582 * try { 2318 // try {
2583 * try { 2319 // jump intr2_exit; <<< gets its own tryNo call label so inner try knows where to restore to
2584 * jump intr2_exit; <<< gets its own tryNo call label so inner try knows where to restore to 2320 // } finally {
2585 * } finally { 2321 // llOwnerSay ("exiting inner");
2586 * llOwnerSay ("exiting inner"); 2322 // }
2587 * } 2323 // jump outtry2;
2588 * jump outtry2; 2324 // @intr2_exit; jump intr1_exit; <<< gets its own tryNo call label so middle try knows where to restore to
2589 * @intr2_exit; jump intr1_exit; <<< gets its own tryNo call label so middle try knows where to restore to 2325 // @outtry2;
2590 * @outtry2; 2326 // } finally {
2591 * } finally { 2327 // llOwnerSay ("exiting middle");
2592 * llOwnerSay ("exiting middle"); 2328 // }
2593 * } 2329 // jump outtry1;
2594 * jump outtry1; 2330 // @intr1_exit: jump exit; <<< gets its own tryNo call label so outer try knows where to restore to
2595 * @intr1_exit: jump exit; <<< gets its own tryNo call label so outer try knows where to restore to 2331 // @outtry1;
2596 * @outtry1; 2332 // } finally {
2597 * } finally { 2333 // llOwnerSay ("exiting outer");
2598 * llOwnerSay ("exiting outer"); 2334 // }
2599 * } 2335 // @exit;
2600 * @exit;
2601 */
2602 int level = 0; 2336 int level = 0;
2603 while(finallyBlocksCalled.Count > 1) 2337 while(finallyBlocksCalled.Count > 1)
2604 { 2338 {
@@ -2615,12 +2349,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2615 target = iLeave.jumpIntoLabel; 2349 target = iLeave.jumpIntoLabel;
2616 } 2350 }
2617 2351
2618 /* 2352 // Finally output the branch/leave opcode.
2619 * Finally output the branch/leave opcode. 2353 // If using Leave, prefix with a call label in case the corresponding finally block
2620 * If using Leave, prefix with a call label in case the corresponding finally block 2354 // calls CheckRun() and that CheckRun() captures the stack, it will have a point to
2621 * calls CheckRun() and that CheckRun() captures the stack, it will have a point to 2355 // restore to that will properly jump back into the finally block.
2622 * restore to that will properly jump back into the finally block.
2623 */
2624 if(useLeave) 2356 if(useLeave)
2625 { 2357 {
2626 new CallLabel(this, errorAt); 2358 new CallLabel(this, errorAt);
@@ -2650,13 +2382,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2650 EmitCallCheckRun(labelStmt, false); 2382 EmitCallCheckRun(labelStmt, false);
2651 } 2383 }
2652 2384
2653 /* 2385 // We are going to say that the label falls through.
2654 * We are going to say that the label falls through. 2386 // It would be nice if we could analyze all referencing
2655 * It would be nice if we could analyze all referencing 2387 // goto's to see if all of them are not used but we are
2656 * goto's to see if all of them are not used but we are 2388 // going to assume that if the script writer put a label
2657 * going to assume that if the script writer put a label 2389 // somewhere, it is probably going to be used.
2658 * somewhere, it is probably going to be used.
2659 */
2660 mightGetHere = true; 2390 mightGetHere = true;
2661 } 2391 }
2662 2392
@@ -2670,34 +2400,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2670 */ 2400 */
2671 private void GenerateStmtNewobj(TokenStmtNewobj newobjStmt) 2401 private void GenerateStmtNewobj(TokenStmtNewobj newobjStmt)
2672 { 2402 {
2673 /* 2403 // First off, malloc a new empty XMRSDTypeClObj object
2674 * First off, malloc a new empty XMRSDTypeClObj object 2404 // then call the XMRSDTypeClObj()-level constructor.
2675 * then call the XMRSDTypeClObj()-level constructor. 2405 // Store the result in local var $objptr.
2676 * Store the result in local var $objptr.
2677 */
2678 newobjStmt.objptrVar.location.PopPre(this, newobjStmt); 2406 newobjStmt.objptrVar.location.PopPre(this, newobjStmt);
2679 ilGen.Emit(newobjStmt, OpCodes.Ldarg_0); 2407 ilGen.Emit(newobjStmt, OpCodes.Ldarg_0);
2680 ilGen.Emit(newobjStmt, OpCodes.Ldc_I4, curDeclFunc.sdtClass.sdTypeIndex); 2408 ilGen.Emit(newobjStmt, OpCodes.Ldc_I4, curDeclFunc.sdtClass.sdTypeIndex);
2681 ilGen.Emit(newobjStmt, OpCodes.Newobj, sdtClassConstructorInfo); 2409 ilGen.Emit(newobjStmt, OpCodes.Newobj, sdtClassConstructorInfo);
2682 newobjStmt.objptrVar.location.PopPost(this, newobjStmt); 2410 newobjStmt.objptrVar.location.PopPost(this, newobjStmt);
2683 2411
2684 /* 2412 // Now call the script-level constructor.
2685 * Now call the script-level constructor. 2413 // Pass the object pointer in $objptr as it's 'this' argument.
2686 * Pass the object pointer in $objptr as it's 'this' argument. 2414 // The rest of the args are the script-visible args and are just copied from $new() call.
2687 * The rest of the args are the script-visible args and are just copied from $new() call.
2688 */
2689 GenerateFromRValCall(newobjStmt.rValCall); 2415 GenerateFromRValCall(newobjStmt.rValCall);
2690 2416
2691 /* 2417 // Put object pointer in retval so it gets returned to caller.
2692 * Put object pointer in retval so it gets returned to caller.
2693 */
2694 newobjStmt.objptrVar.location.PushVal(this, newobjStmt); 2418 newobjStmt.objptrVar.location.PushVal(this, newobjStmt);
2695 ilGen.Emit(newobjStmt, OpCodes.Stloc, retValue); 2419 ilGen.Emit(newobjStmt, OpCodes.Stloc, retValue);
2696 2420
2697 /* 2421 // Exit the function like a return statement.
2698 * Exit the function like a return statement. 2422 // And thus we don't fall through.
2699 * And thus we don't fall through.
2700 */
2701 ilGen.Emit(newobjStmt, OpCodes.Leave, retLabel); 2423 ilGen.Emit(newobjStmt, OpCodes.Leave, retLabel);
2702 mightGetHere = false; 2424 mightGetHere = false;
2703 } 2425 }
@@ -2740,10 +2462,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2740 ilGen.Emit(retStmt, OpCodes.Stloc, retValue); 2462 ilGen.Emit(retStmt, OpCodes.Stloc, retValue);
2741 } 2463 }
2742 2464
2743 /* 2465 // Use a OpCodes.Leave instruction to break out of any try { } blocks.
2744 * Use a OpCodes.Leave instruction to break out of any try { } blocks. 2466 // All Leave's inside script-defined try { } need call labels (see GenerateStmtTry()).
2745 * All Leave's inside script-defined try { } need call labels (see GenerateStmtTry()).
2746 */
2747 bool brokeOutOfTry = false; 2467 bool brokeOutOfTry = false;
2748 for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock) 2468 for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock)
2749 { 2469 {
@@ -2759,9 +2479,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2759 if(brokeOutOfTry) 2479 if(brokeOutOfTry)
2760 openCallLabel = null; 2480 openCallLabel = null;
2761 2481
2762 /* 2482 // 'return' statements never fall through.
2763 * 'return' statements never fall through.
2764 */
2765 mightGetHere = false; 2483 mightGetHere = false;
2766 } 2484 }
2767 2485
@@ -2787,10 +2505,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2787 2505
2788 int index = 0; // 'default' state 2506 int index = 0; // 'default' state
2789 2507
2790 /* 2508 // Set new state value by throwing an exception.
2791 * Set new state value by throwing an exception. 2509 // These exceptions aren't catchable by script-level try { } catch { }.
2792 * These exceptions aren't catchable by script-level try { } catch { }.
2793 */
2794 if((stateStmt.state != null) && !stateIndices.TryGetValue(stateStmt.state.val, out index)) 2510 if((stateStmt.state != null) && !stateIndices.TryGetValue(stateStmt.state.val, out index))
2795 { 2511 {
2796 // The moron XEngine compiles scripts that reference undefined states. 2512 // The moron XEngine compiles scripts that reference undefined states.
@@ -2808,9 +2524,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2808 } 2524 }
2809 ilGen.Emit(stateStmt, OpCodes.Throw); 2525 ilGen.Emit(stateStmt, OpCodes.Throw);
2810 2526
2811 /* 2527 // 'state' statements never fall through.
2812 * 'state' statements never fall through.
2813 */
2814 mightGetHere = false; 2528 mightGetHere = false;
2815 } 2529 }
2816 2530
@@ -2822,22 +2536,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2822 if(!mightGetHere) 2536 if(!mightGetHere)
2823 return; 2537 return;
2824 2538
2825 /* 2539 // Output code to calculate index.
2826 * Output code to calculate index.
2827 */
2828 CompValu testRVal = GenerateFromRVal(switchStmt.testRVal); 2540 CompValu testRVal = GenerateFromRVal(switchStmt.testRVal);
2829 2541
2830 /* 2542 // Generate code based on string or integer index.
2831 * Generate code based on string or integer index.
2832 */
2833 if((testRVal.type is TokenTypeKey) || (testRVal.type is TokenTypeStr)) 2543 if((testRVal.type is TokenTypeKey) || (testRVal.type is TokenTypeStr))
2834 {
2835 GenerateStmtSwitchStr(testRVal, switchStmt); 2544 GenerateStmtSwitchStr(testRVal, switchStmt);
2836 }
2837 else 2545 else
2838 {
2839 GenerateStmtSwitchInt(testRVal, switchStmt); 2546 GenerateStmtSwitchInt(testRVal, switchStmt);
2840 }
2841 } 2547 }
2842 2548
2843 private void GenerateStmtSwitchInt(CompValu testRVal, TokenStmtSwitch switchStmt) 2549 private void GenerateStmtSwitchInt(CompValu testRVal, TokenStmtSwitch switchStmt)
@@ -2851,17 +2557,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2851 2557
2852 curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); 2558 curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique);
2853 2559
2854 /* 2560 // Build list of cases sorted by ascending values.
2855 * Build list of cases sorted by ascending values. 2561 // There should not be any overlapping of values.
2856 * There should not be any overlapping of values.
2857 */
2858 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) 2562 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase)
2859 { 2563 {
2860 thisCase.label = ilGen.DefineLabel("case_" + thisCase.Unique); 2564 thisCase.label = ilGen.DefineLabel("case_" + thisCase.Unique);
2861 2565
2862 /* 2566 // The default case if any, goes in its own separate slot.
2863 * The default case if any, goes in its own separate slot.
2864 */
2865 if(thisCase.rVal1 == null) 2567 if(thisCase.rVal1 == null)
2866 { 2568 {
2867 if(defaultCase != null) 2569 if(defaultCase != null)
@@ -2875,9 +2577,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2875 continue; 2577 continue;
2876 } 2578 }
2877 2579
2878 /* 2580 // Evaluate case operands, they must be compile-time integer constants.
2879 * Evaluate case operands, they must be compile-time integer constants.
2880 */
2881 CompValu rVal = GenerateFromRVal(thisCase.rVal1); 2581 CompValu rVal = GenerateFromRVal(thisCase.rVal1);
2882 if(!IsConstIntExpr(rVal, out thisCase.val1)) 2582 if(!IsConstIntExpr(rVal, out thisCase.val1))
2883 { 2583 {
@@ -2900,10 +2600,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2900 return; 2600 return;
2901 } 2601 }
2902 2602
2903 /* 2603 // Insert into list, sorted by value.
2904 * Insert into list, sorted by value. 2604 // Note that both limits are inclusive.
2905 * Note that both limits are inclusive.
2906 */
2907 TokenSwitchCase lastCase = null; 2605 TokenSwitchCase lastCase = null;
2908 TokenSwitchCase nextCase; 2606 TokenSwitchCase nextCase;
2909 for(nextCase = sortedCases; nextCase != null; nextCase = nextCase.nextSortedCase) 2607 for(nextCase = sortedCases; nextCase != null; nextCase = nextCase.nextSortedCase)
@@ -2934,19 +2632,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2934 defaultLabel = ilGen.DefineLabel("default_" + switchStmt.Unique); 2632 defaultLabel = ilGen.DefineLabel("default_" + switchStmt.Unique);
2935 } 2633 }
2936 2634
2937 /* 2635 // Output code to jump to the case statement's labels based on integer index on stack.
2938 * Output code to jump to the case statement's labels based on integer index on stack. 2636 // Note that each case still has the integer index on stack when jumped to.
2939 * Note that each case still has the integer index on stack when jumped to.
2940 */
2941 int offset = 0; 2637 int offset = 0;
2942 for(TokenSwitchCase thisCase = sortedCases; thisCase != null;) 2638 for(TokenSwitchCase thisCase = sortedCases; thisCase != null;)
2943 { 2639 {
2944 2640 // Scan through list of cases to find the maximum number of cases who's numvalues-to-case ratio
2945 /* 2641 // is from 0.5 to 2.0. If such a group is found, use a CIL switch for them. If not, just use a
2946 * Scan through list of cases to find the maximum number of cases who's numvalues-to-case ratio 2642 // compare-and-branch for the current case.
2947 * is from 0.5 to 2.0. If such a group is found, use a CIL switch for them. If not, just use a
2948 * compare-and-branch for the current case.
2949 */
2950 int numCases = 0; 2643 int numCases = 0;
2951 int numFound = 0; 2644 int numFound = 0;
2952 int lowValue = thisCase.val1; 2645 int lowValue = thisCase.val1;
@@ -2963,23 +2656,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2963 } 2656 }
2964 if(numFound > 1) 2657 if(numFound > 1)
2965 { 2658 {
2966 2659 // There is a group of case's, starting with thisCase, that fall within our criteria, ie,
2967 /* 2660 // that have a nice density of meaningful jumps.
2968 * There is a group of case's, starting with thisCase, that fall within our criteria, ie, 2661 //
2969 * that have a nice density of meaningful jumps. 2662 // So first generate an array of jumps to the default label (explicit or implicit).
2970 *
2971 * So first generate an array of jumps to the default label (explicit or implicit).
2972 */
2973 ScriptMyLabel[] labels = new ScriptMyLabel[numValues]; 2663 ScriptMyLabel[] labels = new ScriptMyLabel[numValues];
2974 for(int i = 0; i < numValues; i++) 2664 for(int i = 0; i < numValues; i++)
2975 { 2665 {
2976 labels[i] = defaultLabel; 2666 labels[i] = defaultLabel;
2977 } 2667 }
2978 2668
2979 /* 2669 // Next, for each case in that group, fill in the corresponding array entries to jump to
2980 * Next, for each case in that group, fill in the corresponding array entries to jump to 2670 // that case's label.
2981 * that case's label.
2982 */
2983 do 2671 do
2984 { 2672 {
2985 for(int i = thisCase.val1; i <= thisCase.val2; i++) 2673 for(int i = thisCase.val1; i <= thisCase.val2; i++)
@@ -2989,10 +2677,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2989 thisCase = thisCase.nextSortedCase; 2677 thisCase = thisCase.nextSortedCase;
2990 } while(--numFound > 0); 2678 } while(--numFound > 0);
2991 2679
2992 /* 2680 // Subtract the low value and do the computed jump.
2993 * Subtract the low value and do the computed jump. 2681 // The OpCodes.Switch falls through if out of range (unsigned compare).
2994 * The OpCodes.Switch falls through if out of range (unsigned compare).
2995 */
2996 if(offset != lowValue) 2682 if(offset != lowValue)
2997 { 2683 {
2998 ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); 2684 ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset);
@@ -3004,11 +2690,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3004 } 2690 }
3005 else 2691 else
3006 { 2692 {
3007 2693 // It's not economical to do with a computed jump, so output a subtract/compare/branch
3008 /* 2694 // for thisCase.
3009 * It's not economical to do with a computed jump, so output a subtract/compare/branch
3010 * for thisCase.
3011 */
3012 if(lowValue == thisCase.val2) 2695 if(lowValue == thisCase.val2)
3013 { 2696 {
3014 ilGen.Emit(switchStmt, OpCodes.Dup); 2697 ilGen.Emit(switchStmt, OpCodes.Dup);
@@ -3032,15 +2715,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3032 } 2715 }
3033 ilGen.Emit(switchStmt, OpCodes.Br, defaultLabel); 2716 ilGen.Emit(switchStmt, OpCodes.Br, defaultLabel);
3034 2717
3035 /* 2718 // Output code for the cases themselves, in the order given by the programmer,
3036 * Output code for the cases themselves, in the order given by the programmer, 2719 // so they fall through as programmer wants. This includes the default case, if any.
3037 * so they fall through as programmer wants. This includes the default case, if any. 2720 //
3038 * 2721 // Each label is jumped to with the index still on the stack. So pop it off in case
3039 * Each label is jumped to with the index still on the stack. So pop it off in case 2722 // the case body does a goto outside the switch or a return. If the case body might
3040 * the case body does a goto outside the switch or a return. If the case body might 2723 // fall through to the next case or the bottom of the switch, push a zero so the stack
3041 * fall through to the next case or the bottom of the switch, push a zero so the stack 2724 // matches in all cases.
3042 * matches in all cases.
3043 */
3044 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) 2725 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase)
3045 { 2726 {
3046 ilGen.MarkLabel(thisCase.label); // the branch comes here 2727 ilGen.MarkLabel(thisCase.label); // the branch comes here
@@ -3057,28 +2738,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3057 } 2738 }
3058 } 2739 }
3059 2740
3060 /* 2741 // If no explicit default case, output the default label here.
3061 * If no explicit default case, output the default label here.
3062 */
3063 if(defaultCase == null) 2742 if(defaultCase == null)
3064 { 2743 {
3065 ilGen.MarkLabel(defaultLabel); 2744 ilGen.MarkLabel(defaultLabel);
3066 mightGetHere = true; 2745 mightGetHere = true;
3067 } 2746 }
3068 2747
3069 /* 2748 // If the last case of the switch falls through out the bottom,
3070 * If the last case of the switch falls through out the bottom, 2749 // we have to pop the index still on the stack.
3071 * we have to pop the index still on the stack.
3072 */
3073 if(mightGetHere) 2750 if(mightGetHere)
3074 { 2751 {
3075 ilGen.Emit(switchStmt, OpCodes.Pop); 2752 ilGen.Emit(switchStmt, OpCodes.Pop);
3076 } 2753 }
3077 2754
3078 /* 2755 // Output the 'break' statement target label.
3079 * Output the 'break' statement target label. 2756 // Note that the integer index is not on the stack at this point.
3080 * Note that the integer index is not on the stack at this point.
3081 */
3082 if(curBreakTarg.used) 2757 if(curBreakTarg.used)
3083 { 2758 {
3084 ilGen.MarkLabel(curBreakTarg.label); 2759 ilGen.MarkLabel(curBreakTarg.label);
@@ -3097,9 +2772,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3097 2772
3098 curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); 2773 curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique);
3099 2774
3100 /* 2775 // Make sure value is in a temp so we don't compute it more than once.
3101 * Make sure value is in a temp so we don't compute it more than once.
3102 */
3103 if(!(testRVal is CompValuTemp)) 2776 if(!(testRVal is CompValuTemp))
3104 { 2777 {
3105 CompValuTemp temp = new CompValuTemp(testRVal.type, this); 2778 CompValuTemp temp = new CompValuTemp(testRVal.type, this);
@@ -3108,17 +2781,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3108 testRVal = temp; 2781 testRVal = temp;
3109 } 2782 }
3110 2783
3111 /* 2784 // Build tree of cases.
3112 * Build tree of cases. 2785 // There should not be any overlapping of values.
3113 * There should not be any overlapping of values.
3114 */
3115 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) 2786 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase)
3116 { 2787 {
3117 thisCase.label = ilGen.DefineLabel("case"); 2788 thisCase.label = ilGen.DefineLabel("case");
3118 2789
3119 /* 2790 // The default case if any, goes in its own separate slot.
3120 * The default case if any, goes in its own separate slot.
3121 */
3122 if(thisCase.rVal1 == null) 2791 if(thisCase.rVal1 == null)
3123 { 2792 {
3124 if(defaultCase != null) 2793 if(defaultCase != null)
@@ -3132,9 +2801,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3132 continue; 2801 continue;
3133 } 2802 }
3134 2803
3135 /* 2804 // Evaluate case operands, they must be compile-time string constants.
3136 * Evaluate case operands, they must be compile-time string constants.
3137 */
3138 CompValu rVal = GenerateFromRVal(thisCase.rVal1); 2805 CompValu rVal = GenerateFromRVal(thisCase.rVal1);
3139 if(!IsConstStrExpr(rVal, out thisCase.str1)) 2806 if(!IsConstStrExpr(rVal, out thisCase.str1))
3140 { 2807 {
@@ -3157,31 +2824,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3157 continue; 2824 continue;
3158 } 2825 }
3159 2826
3160 /* 2827 // Insert into list, sorted by value.
3161 * Insert into list, sorted by value. 2828 // Note that both limits are inclusive.
3162 * Note that both limits are inclusive.
3163 */
3164 caseTreeTop = InsertCaseInTree(caseTreeTop, thisCase); 2829 caseTreeTop = InsertCaseInTree(caseTreeTop, thisCase);
3165 } 2830 }
3166 2831
3167 /* 2832 // Balance tree so we end up generating code that does O(log2 n) comparisons.
3168 * Balance tree so we end up generating code that does O(log2 n) comparisons.
3169 */
3170 caseTreeTop = BalanceTree(caseTreeTop); 2833 caseTreeTop = BalanceTree(caseTreeTop);
3171 2834
3172 /* 2835 // Output compare and branch instructions in a tree-like fashion so we do O(log2 n) comparisons.
3173 * Output compare and branch instructions in a tree-like fashion so we do O(log2 n) comparisons.
3174 */
3175 if(defaultLabel == null) 2836 if(defaultLabel == null)
3176 { 2837 {
3177 defaultLabel = ilGen.DefineLabel("default"); 2838 defaultLabel = ilGen.DefineLabel("default");
3178 } 2839 }
3179 OutputStrCase(testRVal, caseTreeTop, defaultLabel); 2840 OutputStrCase(testRVal, caseTreeTop, defaultLabel);
3180 2841
3181 /* 2842 // Output code for the cases themselves, in the order given by the programmer,
3182 * Output code for the cases themselves, in the order given by the programmer, 2843 // so they fall through as programmer wants. This includes the default case, if any.
3183 * so they fall through as programmer wants. This includes the default case, if any.
3184 */
3185 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) 2844 for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase)
3186 { 2845 {
3187 ilGen.MarkLabel(thisCase.label); // the branch comes here 2846 ilGen.MarkLabel(thisCase.label); // the branch comes here
@@ -3192,18 +2851,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3192 } 2851 }
3193 } 2852 }
3194 2853
3195 /* 2854 // If no explicit default case, output the default label here.
3196 * If no explicit default case, output the default label here.
3197 */
3198 if(defaultCase == null) 2855 if(defaultCase == null)
3199 { 2856 {
3200 ilGen.MarkLabel(defaultLabel); 2857 ilGen.MarkLabel(defaultLabel);
3201 mightGetHere = true; 2858 mightGetHere = true;
3202 } 2859 }
3203 2860
3204 /* 2861 // Output the 'break' statement target label.
3205 * Output the 'break' statement target label.
3206 */
3207 if(curBreakTarg.used) 2862 if(curBreakTarg.used)
3208 { 2863 {
3209 ilGen.MarkLabel(curBreakTarg.label); 2864 ilGen.MarkLabel(curBreakTarg.label);
@@ -3268,10 +2923,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3268 int hc = CountTree(r.higherCase); 2923 int hc = CountTree(r.higherCase);
3269 TokenSwitchCase n, x; 2924 TokenSwitchCase n, x;
3270 2925
3271 /* 2926 // If lower side is heavy, move highest nodes from lower side to
3272 * If lower side is heavy, move highest nodes from lower side to 2927 // higher side until balanced.
3273 * higher side until balanced.
3274 */
3275 while(lc > hc + 1) 2928 while(lc > hc + 1)
3276 { 2929 {
3277 x = ExtractHighest(r.lowerCase, out n); 2930 x = ExtractHighest(r.lowerCase, out n);
@@ -3283,10 +2936,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3283 hc++; 2936 hc++;
3284 } 2937 }
3285 2938
3286 /* 2939 // If higher side is heavy, move lowest nodes from higher side to
3287 * If higher side is heavy, move lowest nodes from higher side to 2940 // lower side until balanced.
3288 * lower side until balanced.
3289 */
3290 while(hc > lc + 1) 2941 while(hc > lc + 1)
3291 { 2942 {
3292 x = ExtractLowest(r.higherCase, out n); 2943 x = ExtractLowest(r.higherCase, out n);
@@ -3298,9 +2949,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3298 hc--; 2949 hc--;
3299 } 2950 }
3300 2951
3301 /* 2952 // Now balance each side because they can be lopsided individually.
3302 * Now balance each side because they can be lopsided individually.
3303 */
3304 r.lowerCase = BalanceTree(r.lowerCase); 2953 r.lowerCase = BalanceTree(r.lowerCase);
3305 r.higherCase = BalanceTree(r.higherCase); 2954 r.higherCase = BalanceTree(r.higherCase);
3306 return r; 2955 return r;
@@ -3359,10 +3008,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3359 */ 3008 */
3360 private void OutputStrCase(CompValu testRVal, TokenSwitchCase thisCase, ScriptMyLabel defaultLabel) 3009 private void OutputStrCase(CompValu testRVal, TokenSwitchCase thisCase, ScriptMyLabel defaultLabel)
3361 { 3010 {
3362 /* 3011 // If nothing lower on tree and there is a single case value,
3363 * If nothing lower on tree and there is a single case value, 3012 // just do one compare for equality.
3364 * just do one compare for equality.
3365 */
3366 if((thisCase.lowerCase == null) && (thisCase.higherCase == null) && (thisCase.str1 == thisCase.str2)) 3013 if((thisCase.lowerCase == null) && (thisCase.higherCase == null) && (thisCase.str1 == thisCase.str2))
3367 { 3014 {
3368 testRVal.PushVal(this, thisCase, tokenTypeStr); 3015 testRVal.PushVal(this, thisCase, tokenTypeStr);
@@ -3374,28 +3021,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3374 return; 3021 return;
3375 } 3022 }
3376 3023
3377 /* 3024 // Determine where to jump if switch value is lower than lower case value.
3378 * Determine where to jump if switch value is lower than lower case value.
3379 */
3380 ScriptMyLabel lowerLabel = defaultLabel; 3025 ScriptMyLabel lowerLabel = defaultLabel;
3381 if(thisCase.lowerCase != null) 3026 if(thisCase.lowerCase != null)
3382 { 3027 {
3383 lowerLabel = ilGen.DefineLabel("lower"); 3028 lowerLabel = ilGen.DefineLabel("lower");
3384 } 3029 }
3385 3030
3386 /* 3031 // If single case value, put comparison result in this temp.
3387 * If single case value, put comparison result in this temp.
3388 */
3389 CompValuTemp cmpv1 = null; 3032 CompValuTemp cmpv1 = null;
3390 if(thisCase.str1 == thisCase.str2) 3033 if(thisCase.str1 == thisCase.str2)
3391 { 3034 {
3392 cmpv1 = new CompValuTemp(tokenTypeInt, this); 3035 cmpv1 = new CompValuTemp(tokenTypeInt, this);
3393 } 3036 }
3394 3037
3395 /* 3038 // If switch value .lt. lower case value, jump to lower label.
3396 * If switch value .lt. lower case value, jump to lower label. 3039 // Maybe save comparison result in a temp.
3397 * Maybe save comparison result in a temp.
3398 */
3399 testRVal.PushVal(this, thisCase, tokenTypeStr); 3040 testRVal.PushVal(this, thisCase, tokenTypeStr);
3400 ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1); 3041 ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1);
3401 ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); 3042 ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal);
@@ -3408,10 +3049,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3408 ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); 3049 ilGen.Emit(thisCase, OpCodes.Ldc_I4_0);
3409 ilGen.Emit(thisCase, OpCodes.Blt, lowerLabel); 3050 ilGen.Emit(thisCase, OpCodes.Blt, lowerLabel);
3410 3051
3411 /* 3052 // If switch value .le. higher case value, jump to case code.
3412 * If switch value .le. higher case value, jump to case code. 3053 // Maybe get comparison from the temp.
3413 * Maybe get comparison from the temp.
3414 */
3415 if(cmpv1 == null) 3054 if(cmpv1 == null)
3416 { 3055 {
3417 testRVal.PushVal(this, thisCase, tokenTypeStr); 3056 testRVal.PushVal(this, thisCase, tokenTypeStr);
@@ -3426,9 +3065,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3426 ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); 3065 ilGen.Emit(thisCase, OpCodes.Ldc_I4_0);
3427 ilGen.Emit(thisCase, OpCodes.Ble, thisCase.label); 3066 ilGen.Emit(thisCase, OpCodes.Ble, thisCase.label);
3428 3067
3429 /* 3068 // Output code for higher comparison if any.
3430 * Output code for higher comparison if any.
3431 */
3432 if(thisCase.higherCase == null) 3069 if(thisCase.higherCase == null)
3433 { 3070 {
3434 ilGen.Emit(thisCase, OpCodes.Br, defaultLabel); 3071 ilGen.Emit(thisCase, OpCodes.Br, defaultLabel);
@@ -3438,9 +3075,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3438 OutputStrCase(testRVal, thisCase.higherCase, defaultLabel); 3075 OutputStrCase(testRVal, thisCase.higherCase, defaultLabel);
3439 } 3076 }
3440 3077
3441 /* 3078 // Output code for lower comparison if any.
3442 * Output code for lower comparison if any.
3443 */
3444 if(thisCase.lowerCase != null) 3079 if(thisCase.lowerCase != null)
3445 { 3080 {
3446 ilGen.MarkLabel(lowerLabel); 3081 ilGen.MarkLabel(lowerLabel);
@@ -3457,14 +3092,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3457 if(!mightGetHere) 3092 if(!mightGetHere)
3458 return; 3093 return;
3459 3094
3460 /* 3095 // 'throw' statements never fall through.
3461 * 'throw' statements never fall through.
3462 */
3463 mightGetHere = false; 3096 mightGetHere = false;
3464 3097
3465 /* 3098 // Output code for either a throw or a rethrow.
3466 * Output code for either a throw or a rethrow.
3467 */
3468 if(throwStmt.rVal == null) 3099 if(throwStmt.rVal == null)
3469 { 3100 {
3470 for(TokenStmtBlock blk = curStmtBlock; blk != null; blk = blk.outerStmtBlock) 3101 for(TokenStmtBlock blk = curStmtBlock; blk != null; blk = blk.outerStmtBlock)
@@ -3506,24 +3137,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3506 throw new Exception("can't have both catch and finally on same try"); 3137 throw new Exception("can't have both catch and finally on same try");
3507 } 3138 }
3508 3139
3509 /* 3140 // Stack the call labels.
3510 * Stack the call labels. 3141 // Try blocks have their own series of call labels.
3511 * Try blocks have their own series of call labels.
3512 */
3513 ScriptMyLocal saveCallNo = actCallNo; 3142 ScriptMyLocal saveCallNo = actCallNo;
3514 LinkedList<CallLabel> saveCallLabels = actCallLabels; 3143 LinkedList<CallLabel> saveCallLabels = actCallLabels;
3515 3144
3516 /* 3145 // Generate code for either try { } catch { } or try { } finally { }.
3517 * Generate code for either try { } catch { } or try { } finally { }.
3518 */
3519 if(tryStmt.catchStmt != null) 3146 if(tryStmt.catchStmt != null)
3520 GenerateStmtTryCatch(tryStmt); 3147 GenerateStmtTryCatch(tryStmt);
3521 if(tryStmt.finallyStmt != null) 3148 if(tryStmt.finallyStmt != null)
3522 GenerateStmtTryFinally(tryStmt); 3149 GenerateStmtTryFinally(tryStmt);
3523 3150
3524 /* 3151 // Restore call labels.
3525 * Restore call labels.
3526 */
3527 actCallNo = saveCallNo; 3152 actCallNo = saveCallNo;
3528 actCallLabels = saveCallLabels; 3153 actCallLabels = saveCallLabels;
3529 } 3154 }
@@ -4017,10 +3642,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4017 */ 3642 */
4018 private void GenerateDeclVar(TokenDeclVar declVar) 3643 private void GenerateDeclVar(TokenDeclVar declVar)
4019 { 3644 {
4020 /* 3645 // Script gave us an initialization value, so just store init value in var like an assignment statement.
4021 * Script gave us an initialization value, so just store init value in var like an assignment statement. 3646 // If no init given, set it to its default value.
4022 * If no init given, set it to its default value.
4023 */
4024 CompValu local = declVar.location; 3647 CompValu local = declVar.location;
4025 if(declVar.init != null) 3648 if(declVar.init != null)
4026 { 3649 {
@@ -4070,14 +3693,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4070 { 3693 {
4071 CompValu subCompValu; 3694 CompValu subCompValu;
4072 3695
4073 /* 3696 // Compute location of array itself.
4074 * Compute location of array itself.
4075 */
4076 CompValu baseCompValu = GenerateFromRVal(lVal.baseRVal); 3697 CompValu baseCompValu = GenerateFromRVal(lVal.baseRVal);
4077 3698
4078 /* 3699 // Maybe it is a fixed array access.
4079 * Maybe it is a fixed array access.
4080 */
4081 string basetypestring = baseCompValu.type.ToString(); 3700 string basetypestring = baseCompValu.type.ToString();
4082 if(basetypestring.EndsWith("]")) 3701 if(basetypestring.EndsWith("]"))
4083 { 3702 {
@@ -4106,9 +3725,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4106 return new CompValuFixArEl(this, baseCompValu, subCompValus); 3725 return new CompValuFixArEl(this, baseCompValu, subCompValus);
4107 } 3726 }
4108 3727
4109 /* 3728 // Maybe it is accessing the $idxprop property of a script-defined class.
4110 * Maybe it is accessing the $idxprop property of a script-defined class.
4111 */
4112 if(baseCompValu.type is TokenTypeSDTypeClass) 3729 if(baseCompValu.type is TokenTypeSDTypeClass)
4113 { 3730 {
4114 TokenName name = new TokenName(lVal, "$idxprop"); 3731 TokenName name = new TokenName(lVal, "$idxprop");
@@ -4133,9 +3750,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4133 3750
4134 } 3751 }
4135 3752
4136 /* 3753 // Maybe they are accessing $idxprop property of a script-defined interface.
4137 * Maybe they are accessing $idxprop property of a script-defined interface.
4138 */
4139 if(baseCompValu.type is TokenTypeSDTypeInterface) 3754 if(baseCompValu.type is TokenTypeSDTypeInterface)
4140 { 3755 {
4141 TokenName name = new TokenName(lVal, "$idxprop"); 3756 TokenName name = new TokenName(lVal, "$idxprop");
@@ -4152,27 +3767,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4152 return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus); 3767 return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus);
4153 } 3768 }
4154 3769
4155 /* 3770 // Maybe it is extracting a character from a string.
4156 * Maybe it is extracting a character from a string.
4157 */
4158 if((baseCompValu.type is TokenTypeKey) || (baseCompValu.type is TokenTypeStr)) 3771 if((baseCompValu.type is TokenTypeKey) || (baseCompValu.type is TokenTypeStr))
4159 { 3772 {
4160 subCompValu = GenerateFromRVal(lVal.subRVal); 3773 subCompValu = GenerateFromRVal(lVal.subRVal);
4161 return new CompValuStrChr(new TokenTypeChar(lVal), baseCompValu, subCompValu); 3774 return new CompValuStrChr(new TokenTypeChar(lVal), baseCompValu, subCompValu);
4162 } 3775 }
4163 3776
4164 /* 3777 // Maybe it is extracting an element from a list.
4165 * Maybe it is extracting an element from a list.
4166 */
4167 if(baseCompValu.type is TokenTypeList) 3778 if(baseCompValu.type is TokenTypeList)
4168 { 3779 {
4169 subCompValu = GenerateFromRVal(lVal.subRVal); 3780 subCompValu = GenerateFromRVal(lVal.subRVal);
4170 return new CompValuListEl(new TokenTypeObject(lVal), baseCompValu, subCompValu); 3781 return new CompValuListEl(new TokenTypeObject(lVal), baseCompValu, subCompValu);
4171 } 3782 }
4172 3783
4173 /* 3784 // Access should be to XMR_Array otherwise.
4174 * Access should be to XMR_Array otherwise.
4175 */
4176 if(!(baseCompValu.type is TokenTypeArray)) 3785 if(!(baseCompValu.type is TokenTypeArray))
4177 { 3786 {
4178 ErrorMsg(lVal, "taking subscript of non-array"); 3787 ErrorMsg(lVal, "taking subscript of non-array");
@@ -4286,9 +3895,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4286 CompValu baseRVal = GenerateFromRVal(lVal.baseRVal); 3895 CompValu baseRVal = GenerateFromRVal(lVal.baseRVal);
4287 string fieldName = lVal.fieldName.val + ArgSigString(argsig); 3896 string fieldName = lVal.fieldName.val + ArgSigString(argsig);
4288 3897
4289 /* 3898 // Maybe they are accessing an instance field, method or property of a script-defined class.
4290 * Maybe they are accessing an instance field, method or property of a script-defined class.
4291 */
4292 if(baseRVal.type is TokenTypeSDTypeClass) 3899 if(baseRVal.type is TokenTypeSDTypeClass)
4293 { 3900 {
4294 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; 3901 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type;
@@ -4303,9 +3910,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4303 return new CompValuVoid(lVal.fieldName); 3910 return new CompValuVoid(lVal.fieldName);
4304 } 3911 }
4305 3912
4306 /* 3913 // Maybe they are accessing a method or property of a script-defined interface.
4307 * Maybe they are accessing a method or property of a script-defined interface.
4308 */
4309 if(baseRVal.type is TokenTypeSDTypeInterface) 3914 if(baseRVal.type is TokenTypeSDTypeInterface)
4310 { 3915 {
4311 TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseRVal.type; 3916 TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseRVal.type;
@@ -4318,9 +3923,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4318 return new CompValuVoid(lVal.fieldName); 3923 return new CompValuVoid(lVal.fieldName);
4319 } 3924 }
4320 3925
4321 /* 3926 // Since we only have a few built-in types with fields, just pound them out.
4322 * Since we only have a few built-in types with fields, just pound them out.
4323 */
4324 if(baseRVal.type is TokenTypeArray) 3927 if(baseRVal.type is TokenTypeArray)
4325 { 3928 {
4326 3929
@@ -4392,9 +3995,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4392 */ 3995 */
4393 private CompValu GenerateFromLValName(TokenLValName lVal, TokenType[] argsig) 3996 private CompValu GenerateFromLValName(TokenLValName lVal, TokenType[] argsig)
4394 { 3997 {
4395 /* 3998 // Look in variable stack then look for built-in constants and functions.
4396 * Look in variable stack then look for built-in constants and functions.
4397 */
4398 TokenDeclVar var = FindNamedVar(lVal, argsig); 3999 TokenDeclVar var = FindNamedVar(lVal, argsig);
4399 if(var == null) 4000 if(var == null)
4400 { 4001 {
@@ -4402,9 +4003,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4402 return new CompValuVoid(lVal); 4003 return new CompValuVoid(lVal);
4403 } 4004 }
4404 4005
4405 /* 4006 // Maybe it has an implied 'this.' on the front.
4406 * Maybe it has an implied 'this.' on the front.
4407 */
4408 if((var.sdtClass != null) && ((var.sdtFlags & ScriptReduce.SDT_STATIC) == 0)) 4007 if((var.sdtClass != null) && ((var.sdtFlags & ScriptReduce.SDT_STATIC) == 0))
4409 { 4008 {
4410 4009
@@ -4414,33 +4013,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4414 return new CompValuVoid(lVal); 4013 return new CompValuVoid(lVal);
4415 } 4014 }
4416 4015
4417 /* 4016 // Don't allow something such as:
4418 * Don't allow something such as: 4017 //
4419 * 4018 // class A {
4420 * class A { 4019 // integer I;
4421 * integer I; 4020 // class B {
4422 * class B { 4021 // Print ()
4423 * Print () 4022 // {
4424 * { 4023 // llOwnerSay ("I=" + (string)I); <- access to I not allowed inside class B.
4425 * llOwnerSay ("I=" + (string)I); <- access to I not allowed inside class B. 4024 // explicit reference required as we don't
4426 * explicit reference required as we don't 4025 // have a valid reference to class A.
4427 * have a valid reference to class A. 4026 // }
4428 * } 4027 // }
4429 * } 4028 // }
4430 * } 4029 //
4431 * 4030 // But do allow something such as:
4432 * But do allow something such as: 4031 //
4433 * 4032 // class A {
4434 * class A { 4033 // integer I;
4435 * integer I; 4034 // }
4436 * } 4035 // class B : A {
4437 * class B : A { 4036 // Print ()
4438 * Print () 4037 // {
4439 * { 4038 // llOwnerSay ("I=" + (string)I);
4440 * llOwnerSay ("I=" + (string)I); 4039 // }
4441 * } 4040 // }
4442 * }
4443 */
4444 for(TokenDeclSDType c = curDeclFunc.sdtClass; c != var.sdtClass; c = c.extends) 4041 for(TokenDeclSDType c = curDeclFunc.sdtClass; c != var.sdtClass; c = c.extends)
4445 { 4042 {
4446 if(c == null) 4043 if(c == null)
@@ -4455,9 +4052,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4455 return AccessInstanceMember(var, thisCompValu, lVal, false); 4052 return AccessInstanceMember(var, thisCompValu, lVal, false);
4456 } 4053 }
4457 4054
4458 /* 4055 // It's a local variable, static field, global, constant, etc.
4459 * It's a local variable, static field, global, constant, etc.
4460 */
4461 return var.location; 4056 return var.location;
4462 } 4057 }
4463 4058
@@ -4487,9 +4082,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4487 TokenType stType = lVal.baseType; 4082 TokenType stType = lVal.baseType;
4488 string fieldName = lVal.fieldName.val + ArgSigString(argsig); 4083 string fieldName = lVal.fieldName.val + ArgSigString(argsig);
4489 4084
4490 /* 4085 // Maybe they are accessing a static member of a script-defined class.
4491 * Maybe they are accessing a static member of a script-defined class.
4492 */
4493 if(stType is TokenTypeSDTypeClass) 4086 if(stType is TokenTypeSDTypeClass)
4494 { 4087 {
4495 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)stType; 4088 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)stType;
@@ -4529,9 +4122,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4529 { 4122 {
4530 errorMessageToken = rVal; 4123 errorMessageToken = rVal;
4531 4124
4532 /* 4125 // Maybe the expression can be converted to a constant.
4533 * Maybe the expression can be converted to a constant.
4534 */
4535 bool didOne; 4126 bool didOne;
4536 do 4127 do
4537 { 4128 {
@@ -4539,9 +4130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4539 rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); 4130 rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne);
4540 } while(didOne); 4131 } while(didOne);
4541 4132
4542 /* 4133 // Generate code for the computation and return resulting type and location.
4543 * Generate code for the computation and return resulting type and location.
4544 */
4545 CompValu cVal = null; 4134 CompValu cVal = null;
4546 if(rVal is TokenRValAsnPost) 4135 if(rVal is TokenRValAsnPost)
4547 cVal = GenerateFromRValAsnPost((TokenRValAsnPost)rVal); 4136 cVal = GenerateFromRValAsnPost((TokenRValAsnPost)rVal);
@@ -4583,9 +4172,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4583 if(cVal == null) 4172 if(cVal == null)
4584 throw new Exception("bad rval class " + rVal.GetType().ToString()); 4173 throw new Exception("bad rval class " + rVal.GetType().ToString());
4585 4174
4586 /* 4175 // Sanity check.
4587 * Sanity check.
4588 */
4589 if(!youveAnError) 4176 if(!youveAnError)
4590 { 4177 {
4591 if(cVal.type == null) 4178 if(cVal.type == null)
@@ -4616,30 +4203,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4616 CompValu left, right; 4203 CompValu left, right;
4617 string opcodeIndex = token.opcode.ToString(); 4204 string opcodeIndex = token.opcode.ToString();
4618 4205
4619 /* 4206 // Comma operators are special, as they say to compute the left-hand value and
4620 * Comma operators are special, as they say to compute the left-hand value and 4207 // discard it, then compute the right-hand argument and that is the result.
4621 * discard it, then compute the right-hand argument and that is the result.
4622 */
4623 if(opcodeIndex == ",") 4208 if(opcodeIndex == ",")
4624 { 4209 {
4625 4210 // Compute left-hand operand but throw away result.
4626 /*
4627 * Compute left-hand operand but throw away result.
4628 */
4629 GenerateFromRVal(token.rValLeft); 4211 GenerateFromRVal(token.rValLeft);
4630 4212
4631 /* 4213 // Compute right-hand operand and that is the value of the expression.
4632 * Compute right-hand operand and that is the value of the expression.
4633 */
4634 return GenerateFromRVal(token.rValRight); 4214 return GenerateFromRVal(token.rValRight);
4635 } 4215 }
4636 4216
4637 /* 4217 // Simple overwriting assignments are their own special case,
4638 * Simple overwriting assignments are their own special case, 4218 // as we want to cast the R-value to the type of the L-value.
4639 * as we want to cast the R-value to the type of the L-value. 4219 // And in the case of delegates, we want to use the arg signature
4640 * And in the case of delegates, we want to use the arg signature 4220 // of the delegate to select which overloaded method to use.
4641 * of the delegate to select which overloaded method to use.
4642 */
4643 if(opcodeIndex == "=") 4221 if(opcodeIndex == "=")
4644 { 4222 {
4645 if(!(token.rValLeft is TokenLVal)) 4223 if(!(token.rValLeft is TokenLVal))
@@ -4655,26 +4233,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4655 return left; 4233 return left;
4656 } 4234 }
4657 4235
4658 /* 4236 // There are String.Concat() methods available for 2, 3 and 4 operands.
4659 * There are String.Concat() methods available for 2, 3 and 4 operands. 4237 // So see if we have a string concat op and optimize if so.
4660 * So see if we have a string concat op and optimize if so.
4661 */
4662 if((opcodeIndex == "+") || 4238 if((opcodeIndex == "+") ||
4663 ((opcodeIndex == "+=") && 4239 ((opcodeIndex == "+=") &&
4664 (token.rValLeft is TokenLVal) && 4240 (token.rValLeft is TokenLVal) &&
4665 (token.rValLeft.GetRValType(this, null) is TokenTypeStr))) 4241 (token.rValLeft.GetRValType(this, null) is TokenTypeStr)))
4666 { 4242 {
4667 4243
4668 /* 4244 // We are adding something. Maybe it's a bunch of strings together.
4669 * We are adding something. Maybe it's a bunch of strings together.
4670 */
4671 List<TokenRVal> scorvs = new List<TokenRVal>(); 4245 List<TokenRVal> scorvs = new List<TokenRVal>();
4672 if(StringConcatOperands(token.rValLeft, token.rValRight, scorvs, token.opcode)) 4246 if(StringConcatOperands(token.rValLeft, token.rValRight, scorvs, token.opcode))
4673 { 4247 {
4674 4248 // Evaluate all the operands, right-to-left on purpose per LSL scripting.
4675 /*
4676 * Evaluate all the operands, right-to-left on purpose per LSL scripting.
4677 */
4678 int i; 4249 int i;
4679 int n = scorvs.Count; 4250 int n = scorvs.Count;
4680 CompValu[] scocvs = new CompValu[n]; 4251 CompValu[] scocvs = new CompValu[n];
@@ -4700,10 +4271,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4700 } 4271 }
4701 retcv.PopPre(this, token); 4272 retcv.PopPre(this, token);
4702 4273
4703 /* 4274 // Call the String.Concat() methods, passing operands in left-to-right order.
4704 * Call the String.Concat() methods, passing operands in left-to-right order. 4275 // Force a cast to string (retcv.type) for each operand.
4705 * Force a cast to string (retcv.type) for each operand.
4706 */
4707 ++i; 4276 ++i;
4708 scocvs[i].PushVal(this, scorvs[i], retcv.type); 4277 scocvs[i].PushVal(this, scorvs[i], retcv.type);
4709 while(i + 3 < n) 4278 while(i + 3 < n)
@@ -4731,18 +4300,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4731 ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat2MethodInfo); 4300 ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat2MethodInfo);
4732 } 4301 }
4733 4302
4734 /* 4303 // Put the result where we want it and return where we put it.
4735 * Put the result where we want it and return where we put it.
4736 */
4737 retcv.PopPost(this, token); 4304 retcv.PopPost(this, token);
4738 return retcv; 4305 return retcv;
4739 } 4306 }
4740 } 4307 }
4741 4308
4742 /* 4309 // If "&&&", it is a short-circuiting AND.
4743 * If "&&&", it is a short-circuiting AND. 4310 // Compute left-hand operand and if true, compute right-hand operand.
4744 * Compute left-hand operand and if true, compute right-hand operand.
4745 */
4746 if(opcodeIndex == "&&&") 4311 if(opcodeIndex == "&&&")
4747 { 4312 {
4748 bool leftVal, rightVal; 4313 bool leftVal, rightVal;
@@ -4791,10 +4356,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4791 return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); 4356 return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0);
4792 } 4357 }
4793 4358
4794 /* 4359 // If "|||", it is a short-circuiting OR.
4795 * If "|||", it is a short-circuiting OR. 4360 // Compute left-hand operand and if false, compute right-hand operand.
4796 * Compute left-hand operand and if false, compute right-hand operand.
4797 */
4798 if(opcodeIndex == "|||") 4361 if(opcodeIndex == "|||")
4799 { 4362 {
4800 bool leftVal, rightVal; 4363 bool leftVal, rightVal;
@@ -4843,17 +4406,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4843 return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); 4406 return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0);
4844 } 4407 }
4845 4408
4846 /* 4409 // Computation of some sort, compute right-hand operand value then left-hand value
4847 * Computation of some sort, compute right-hand operand value then left-hand value 4410 // because LSL is supposed to be right-to-left evaluation.
4848 * because LSL is supposed to be right-to-left evaluation.
4849 */
4850 right = Trivialize(GenerateFromRVal(token.rValRight), token.rValRight); 4411 right = Trivialize(GenerateFromRVal(token.rValRight), token.rValRight);
4851 4412
4852 /* 4413 // If left is a script-defined class and there is a method with the operator's name,
4853 * If left is a script-defined class and there is a method with the operator's name, 4414 // convert this to a call to that method with the right value as its single parameter.
4854 * convert this to a call to that method with the right value as its single parameter. 4415 // Except don't if the right value is 'undef' so they can always compare to undef.
4855 * Except don't if the right value is 'undef' so they can always compare to undef.
4856 */
4857 TokenType leftType = token.rValLeft.GetRValType(this, null); 4416 TokenType leftType = token.rValLeft.GetRValType(this, null);
4858 if((leftType is TokenTypeSDTypeClass) && !(right.type is TokenTypeUndef)) 4417 if((leftType is TokenTypeSDTypeClass) && !(right.type is TokenTypeUndef))
4859 { 4418 {
@@ -4872,28 +4431,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4872 } 4431 }
4873 } 4432 }
4874 4433
4875 /* 4434 // Formulate key string for binOpStrings = (lefttype)(operator)(righttype)
4876 * Formulate key string for binOpStrings = (lefttype)(operator)(righttype)
4877 */
4878 string leftIndex = leftType.ToString(); 4435 string leftIndex = leftType.ToString();
4879 string rightIndex = right.type.ToString(); 4436 string rightIndex = right.type.ToString();
4880 string key = leftIndex + opcodeIndex + rightIndex; 4437 string key = leftIndex + opcodeIndex + rightIndex;
4881 4438
4882 /* 4439 // If that key exists in table, then the operation is defined between those types
4883 * If that key exists in table, then the operation is defined between those types 4440 // ... and it produces an R-value of type as given in the table.
4884 * ... and it produces an R-value of type as given in the table.
4885 */
4886 BinOpStr binOpStr; 4441 BinOpStr binOpStr;
4887 if(BinOpStr.defined.TryGetValue(key, out binOpStr)) 4442 if(BinOpStr.defined.TryGetValue(key, out binOpStr))
4888 { 4443 {
4889 4444 // If table contained an explicit assignment type like +=, output the statement without
4890 /* 4445 // casting the L-value, then return the L-value as the resultant value.
4891 * If table contained an explicit assignment type like +=, output the statement without 4446 //
4892 * casting the L-value, then return the L-value as the resultant value. 4447 // Make sure we don't include comparisons (such as ==, >=, etc).
4893 * 4448 // Nothing like +=, -=, %=, etc, generate a boolean, only the comparisons.
4894 * Make sure we don't include comparisons (such as ==, >=, etc).
4895 * Nothing like +=, -=, %=, etc, generate a boolean, only the comparisons.
4896 */
4897 if((binOpStr.outtype != typeof(bool)) && opcodeIndex.EndsWith("=") && (opcodeIndex != "!=")) 4449 if((binOpStr.outtype != typeof(bool)) && opcodeIndex.EndsWith("=") && (opcodeIndex != "!="))
4898 { 4450 {
4899 if(!(token.rValLeft is TokenLVal)) 4451 if(!(token.rValLeft is TokenLVal))
@@ -4906,21 +4458,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4906 return left; 4458 return left;
4907 } 4459 }
4908 4460
4909 /* 4461 // It's of the form left binop right.
4910 * It's of the form left binop right. 4462 // Compute left, perform operation then put result in a temp.
4911 * Compute left, perform operation then put result in a temp.
4912 */
4913 left = GenerateFromRVal(token.rValLeft); 4463 left = GenerateFromRVal(token.rValLeft);
4914 CompValu retRVal = new CompValuTemp(TokenType.FromSysType(token.opcode, binOpStr.outtype), this); 4464 CompValu retRVal = new CompValuTemp(TokenType.FromSysType(token.opcode, binOpStr.outtype), this);
4915 binOpStr.emitBO(this, token, left, right, retRVal); 4465 binOpStr.emitBO(this, token, left, right, retRVal);
4916 return retRVal; 4466 return retRVal;
4917 } 4467 }
4918 4468
4919 /* 4469 // Nothing in the table, check for comparing object pointers because of the myriad of types possible.
4920 * Nothing in the table, check for comparing object pointers because of the myriad of types possible. 4470 // This will compare list pointers, null pointers, script-defined type pointers, array pointers, etc.
4921 * This will compare list pointers, null pointers, script-defined type pointers, array pointers, etc. 4471 // It will show equal iff the memory addresses are equal and that is good enough.
4922 * It will show equal iff the memory addresses are equal and that is good enough.
4923 */
4924 if(!leftType.ToSysType().IsValueType && !right.type.ToSysType().IsValueType && ((opcodeIndex == "==") || (opcodeIndex == "!="))) 4472 if(!leftType.ToSysType().IsValueType && !right.type.ToSysType().IsValueType && ((opcodeIndex == "==") || (opcodeIndex == "!=")))
4925 { 4473 {
4926 CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); 4474 CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this);
@@ -4937,12 +4485,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4937 return retRVal; 4485 return retRVal;
4938 } 4486 }
4939 4487
4940 /* 4488 // If the opcode ends with "=", it may be something like "+=".
4941 * If the opcode ends with "=", it may be something like "+=". 4489 // So look up the key as if we didn't have the "=" to tell us if the operation is legal.
4942 * So look up the key as if we didn't have the "=" to tell us if the operation is legal. 4490 // Also, the binary operation's output type must be the same as the L-value type.
4943 * Also, the binary operation's output type must be the same as the L-value type. 4491 // Likewise, integer += float not allowed because result is float, but float += integer is ok.
4944 * Likewise, integer += float not allowed because result is float, but float += integer is ok.
4945 */
4946 if(opcodeIndex.EndsWith("=")) 4492 if(opcodeIndex.EndsWith("="))
4947 { 4493 {
4948 key = leftIndex + opcodeIndex.Substring(0, opcodeIndex.Length - 1) + rightIndex; 4494 key = leftIndex + opcodeIndex.Substring(0, opcodeIndex.Length - 1) + rightIndex;
@@ -4959,9 +4505,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4959 return new CompValuVoid(token); 4505 return new CompValuVoid(token);
4960 } 4506 }
4961 4507
4962 /* 4508 // Now we know for something like %= that left%right is legal for the types given.
4963 * Now we know for something like %= that left%right is legal for the types given.
4964 */
4965 left = GenerateFromLVal((TokenLVal)token.rValLeft); 4509 left = GenerateFromLVal((TokenLVal)token.rValLeft);
4966 if(binOpStr.outtype == leftType.ToSysType()) 4510 if(binOpStr.outtype == leftType.ToSysType())
4967 { 4511 {
@@ -4979,9 +4523,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4979 } 4523 }
4980 } 4524 }
4981 4525
4982 /* 4526 // Can't find it, oh well.
4983 * Can't find it, oh well.
4984 */
4985 ErrorMsg(token, "op not defined: " + leftIndex + " " + opcodeIndex + " " + rightIndex); 4527 ErrorMsg(token, "op not defined: " + leftIndex + " " + opcodeIndex + " " + rightIndex);
4986 return new CompValuVoid(token); 4528 return new CompValuVoid(token);
4987 } 4529 }
@@ -5007,26 +4549,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5007 if(!(leftType is TokenTypeStr) && !(rightType is TokenTypeStr)) 4549 if(!(leftType is TokenTypeStr) && !(rightType is TokenTypeStr))
5008 return false; 4550 return false;
5009 4551
5010 /* 4552 // Also, list+string => list so reject that too.
5011 * Also, list+string => list so reject that too. 4553 // Also, string+list => list so reject that too.
5012 * Also, string+list => list so reject that too.
5013 */
5014 if(leftType is TokenTypeList) 4554 if(leftType is TokenTypeList)
5015 return false; 4555 return false;
5016 if(rightType is TokenTypeList) 4556 if(rightType is TokenTypeList)
5017 return false; 4557 return false;
5018 4558
5019 /* 4559 // Append values to the end of the list in left-to-right order.
5020 * Append values to the end of the list in left-to-right order. 4560 // If value is formed from a something+something => string,
5021 * If value is formed from a something+something => string, 4561 // push them as separate values, otherwise push as one value.
5022 * push them as separate values, otherwise push as one value.
5023 */
5024 StringConcatOperand(leftType, leftRVal, scos); 4562 StringConcatOperand(leftType, leftRVal, scos);
5025 StringConcatOperand(rightType, rightRVal, scos); 4563 StringConcatOperand(rightType, rightRVal, scos);
5026 4564
5027 /* 4565 // Maybe constant strings can be concatted.
5028 * Maybe constant strings can be concatted.
5029 */
5030 try 4566 try
5031 { 4567 {
5032 int len; 4568 int len;
@@ -5044,9 +4580,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5044 { 4580 {
5045 } 4581 }
5046 4582
5047 /* 4583 // We pushed some string stuff.
5048 * We pushed some string stuff.
5049 */
5050 return true; 4584 return true;
5051 } 4585 }
5052 4586
@@ -5090,9 +4624,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5090 { 4624 {
5091 CompValu inRVal = GenerateFromRVal(token.rVal); 4625 CompValu inRVal = GenerateFromRVal(token.rVal);
5092 4626
5093 /* 4627 // Script-defined types can define their own methods to handle unary operators.
5094 * Script-defined types can define their own methods to handle unary operators.
5095 */
5096 if(inRVal.type is TokenTypeSDTypeClass) 4628 if(inRVal.type is TokenTypeSDTypeClass)
5097 { 4629 {
5098 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)inRVal.type; 4630 TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)inRVal.type;
@@ -5107,9 +4639,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5107 } 4639 }
5108 } 4640 }
5109 4641
5110 /* 4642 // Otherwise use the default.
5111 * Otherwise use the default.
5112 */
5113 return UnOpGenerate(inRVal, token.opcode); 4643 return UnOpGenerate(inRVal, token.opcode);
5114 } 4644 }
5115 4645
@@ -5120,26 +4650,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5120 { 4650 {
5121 CompValu lVal = GenerateFromLVal(asnPost.lVal); 4651 CompValu lVal = GenerateFromLVal(asnPost.lVal);
5122 4652
5123 /* 4653 // Make up a temp to save original value in.
5124 * Make up a temp to save original value in.
5125 */
5126 CompValuTemp result = new CompValuTemp(lVal.type, this); 4654 CompValuTemp result = new CompValuTemp(lVal.type, this);
5127 4655
5128 /* 4656 // Prepare to pop incremented value back into variable being incremented.
5129 * Prepare to pop incremented value back into variable being incremented.
5130 */
5131 lVal.PopPre(this, asnPost.lVal); 4657 lVal.PopPre(this, asnPost.lVal);
5132 4658
5133 /* 4659 // Copy original value to temp and leave value on stack.
5134 * Copy original value to temp and leave value on stack.
5135 */
5136 lVal.PushVal(this, asnPost.lVal); 4660 lVal.PushVal(this, asnPost.lVal);
5137 ilGen.Emit(asnPost.lVal, OpCodes.Dup); 4661 ilGen.Emit(asnPost.lVal, OpCodes.Dup);
5138 result.Pop(this, asnPost.lVal); 4662 result.Pop(this, asnPost.lVal);
5139 4663
5140 /* 4664 // Perform the ++/--.
5141 * Perform the ++/--.
5142 */
5143 if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) 4665 if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt))
5144 { 4666 {
5145 ilGen.Emit(asnPost, OpCodes.Ldc_I4_1); 4667 ilGen.Emit(asnPost, OpCodes.Ldc_I4_1);
@@ -5170,9 +4692,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5170 throw new Exception("unknown asnPost op"); 4692 throw new Exception("unknown asnPost op");
5171 } 4693 }
5172 4694
5173 /* 4695 // Store new value in original variable.
5174 * Store new value in original variable.
5175 */
5176 lVal.PopPost(this, asnPost.lVal); 4696 lVal.PopPost(this, asnPost.lVal);
5177 4697
5178 return result; 4698 return result;
@@ -5185,24 +4705,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5185 { 4705 {
5186 CompValu lVal = GenerateFromLVal(asnPre.lVal); 4706 CompValu lVal = GenerateFromLVal(asnPre.lVal);
5187 4707
5188 /* 4708 // Make up a temp to put result in.
5189 * Make up a temp to put result in.
5190 */
5191 CompValuTemp result = new CompValuTemp(lVal.type, this); 4709 CompValuTemp result = new CompValuTemp(lVal.type, this);
5192 4710
5193 /* 4711 // Prepare to pop incremented value back into variable being incremented.
5194 * Prepare to pop incremented value back into variable being incremented.
5195 */
5196 lVal.PopPre(this, asnPre.lVal); 4712 lVal.PopPre(this, asnPre.lVal);
5197 4713
5198 /* 4714 // Push original value.
5199 * Push original value.
5200 */
5201 lVal.PushVal(this, asnPre.lVal); 4715 lVal.PushVal(this, asnPre.lVal);
5202 4716
5203 /* 4717 // Perform the ++/--.
5204 * Perform the ++/--.
5205 */
5206 if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) 4718 if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt))
5207 { 4719 {
5208 ilGen.Emit(asnPre, OpCodes.Ldc_I4_1); 4720 ilGen.Emit(asnPre, OpCodes.Ldc_I4_1);
@@ -5233,15 +4745,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5233 throw new Exception("unknown asnPre op"); 4745 throw new Exception("unknown asnPre op");
5234 } 4746 }
5235 4747
5236 /* 4748 // Store new value in temp variable, keeping new value on stack.
5237 * Store new value in temp variable, keeping new value on stack.
5238 */
5239 ilGen.Emit(asnPre.lVal, OpCodes.Dup); 4749 ilGen.Emit(asnPre.lVal, OpCodes.Dup);
5240 result.Pop(this, asnPre.lVal); 4750 result.Pop(this, asnPre.lVal);
5241 4751
5242 /* 4752 // Store new value in original variable.
5243 * Store new value in original variable.
5244 */
5245 lVal.PopPost(this, asnPre.lVal); 4753 lVal.PopPost(this, asnPre.lVal);
5246 4754
5247 return result; 4755 return result;
@@ -5259,11 +4767,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5259 TokenRVal arg; 4767 TokenRVal arg;
5260 TokenType[] argTypes; 4768 TokenType[] argTypes;
5261 4769
5262 /* 4770 // Compute the values of all the function's call arguments.
5263 * Compute the values of all the function's call arguments. 4771 // Save where the computation results are in the argRVals[] array.
5264 * Save where the computation results are in the argRVals[] array. 4772 // Might as well build the argument signature from the argument types, too.
5265 * Might as well build the argument signature from the argument types, too.
5266 */
5267 nargs = call.nArgs; 4773 nargs = call.nArgs;
5268 argRVals = new CompValu[nargs]; 4774 argRVals = new CompValu[nargs];
5269 argTypes = new TokenType[nargs]; 4775 argTypes = new TokenType[nargs];
@@ -5278,9 +4784,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5278 } 4784 }
5279 } 4785 }
5280 4786
5281 /* 4787 // Get function/method's entrypoint that matches the call argument types.
5282 * Get function/method's entrypoint that matches the call argument types.
5283 */
5284 method = GenerateFromRVal(call.meth, argTypes); 4788 method = GenerateFromRVal(call.meth, argTypes);
5285 if(method == null) 4789 if(method == null)
5286 return null; 4790 return null;
@@ -5302,9 +4806,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5302 TokenType retType; 4806 TokenType retType;
5303 TokenType[] argTypes; 4807 TokenType[] argTypes;
5304 4808
5305 /* 4809 // Must be some kind of callable.
5306 * Must be some kind of callable.
5307 */
5308 retType = method.GetRetType(); // TokenTypeVoid if void; null means a variable 4810 retType = method.GetRetType(); // TokenTypeVoid if void; null means a variable
5309 if(retType == null) 4811 if(retType == null)
5310 { 4812 {
@@ -5312,9 +4814,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5312 return new CompValuVoid(call); 4814 return new CompValuVoid(call);
5313 } 4815 }
5314 4816
5315 /* 4817 // Get a location for return value.
5316 * Get a location for return value.
5317 */
5318 if(retType is TokenTypeVoid) 4818 if(retType is TokenTypeVoid)
5319 { 4819 {
5320 result = new CompValuVoid(call); 4820 result = new CompValuVoid(call);
@@ -5324,10 +4824,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5324 result = new CompValuTemp(retType, this); 4824 result = new CompValuTemp(retType, this);
5325 } 4825 }
5326 4826
5327 /* 4827 // Make sure all arguments are trivial, ie, don't involve their own call labels.
5328 * Make sure all arguments are trivial, ie, don't involve their own call labels. 4828 // For any that aren't, output code to calculate the arg and put in a temporary.
5329 * For any that aren't, output code to calculate the arg and put in a temporary.
5330 */
5331 nArgs = argRVals.Length; 4829 nArgs = argRVals.Length;
5332 for(i = 0; i < nArgs; i++) 4830 for(i = 0; i < nArgs; i++)
5333 { 4831 {
@@ -5337,9 +4835,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5337 } 4835 }
5338 } 4836 }
5339 4837
5340 /* 4838 // Inline functions know how to generate their own call.
5341 * Inline functions know how to generate their own call.
5342 */
5343 if(method is CompValuInline) 4839 if(method is CompValuInline)
5344 { 4840 {
5345 CompValuInline inline = (CompValuInline)method; 4841 CompValuInline inline = (CompValuInline)method;
@@ -5347,14 +4843,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5347 return result; 4843 return result;
5348 } 4844 }
5349 4845
5350 /* 4846 // Push whatever the function/method needs as a this argument, if anything.
5351 * Push whatever the function/method needs as a this argument, if anything.
5352 */
5353 method.CallPre(this, call); 4847 method.CallPre(this, call);
5354 4848
5355 /* 4849 // Push the script-visible args, left-to-right.
5356 * Push the script-visible args, left-to-right.
5357 */
5358 argTypes = method.GetArgTypes(); 4850 argTypes = method.GetArgTypes();
5359 for(i = 0; i < nArgs; i++) 4851 for(i = 0; i < nArgs; i++)
5360 { 4852 {
@@ -5368,14 +4860,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5368 } 4860 }
5369 } 4861 }
5370 4862
5371 /* 4863 // Now output call instruction.
5372 * Now output call instruction.
5373 */
5374 method.CallPost(this, call); 4864 method.CallPost(this, call);
5375 4865
5376 /* 4866 // Deal with the return value (if any), by putting it in 'result'.
5377 * Deal with the return value (if any), by putting it in 'result'.
5378 */
5379 result.Pop(this, call, retType); 4867 result.Pop(this, call, retType);
5380 return result; 4868 return result;
5381 } 4869 }
@@ -5402,13 +4890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5402 */ 4890 */
5403 private CompValu GenerateFromRValCast(TokenRValCast cast) 4891 private CompValu GenerateFromRValCast(TokenRValCast cast)
5404 { 4892 {
5405 /* 4893 // If casting to a delegate type, use the argment signature
5406 * If casting to a delegate type, use the argment signature 4894 // of the delegate to help select the function/method, eg,
5407 * of the delegate to help select the function/method, eg, 4895 // '(delegate string(integer))ToString'
5408 * '(delegate string(integer))ToString' 4896 // will select 'string ToString(integer x)'
5409 * will select 'string ToString(integer x)' 4897 // instaead of 'string ToString(float x)' or anything else
5410 * instaead of 'string ToString(float x)' or anything else
5411 */
5412 TokenType[] argsig = null; 4898 TokenType[] argsig = null;
5413 TokenType outType = cast.castTo; 4899 TokenType outType = cast.castTo;
5414 if(outType is TokenTypeSDTypeDelegate) 4900 if(outType is TokenTypeSDTypeDelegate)
@@ -5416,17 +4902,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5416 argsig = ((TokenTypeSDTypeDelegate)outType).decl.GetArgTypes(); 4902 argsig = ((TokenTypeSDTypeDelegate)outType).decl.GetArgTypes();
5417 } 4903 }
5418 4904
5419 /* 4905 // Generate the value that is being cast.
5420 * Generate the value that is being cast. 4906 // If the value is already the requested type, just use it as is.
5421 * If the value is already the requested type, just use it as is.
5422 */
5423 CompValu inRVal = GenerateFromRVal(cast.rVal, argsig); 4907 CompValu inRVal = GenerateFromRVal(cast.rVal, argsig);
5424 if(inRVal.type == outType) 4908 if(inRVal.type == outType)
5425 return inRVal; 4909 return inRVal;
5426 4910
5427 /* 4911 // Different type, generate casting code, putting the result in a temp of the output type.
5428 * Different type, generate casting code, putting the result in a temp of the output type.
5429 */
5430 CompValu outRVal = new CompValuTemp(outType, this); 4912 CompValu outRVal = new CompValuTemp(outType, this);
5431 outRVal.PopPre(this, cast); 4913 outRVal.PopPre(this, cast);
5432 inRVal.PushVal(this, cast, outType, true); 4914 inRVal.PushVal(this, cast, outType, true);
@@ -5511,10 +4993,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5511 */ 4993 */
5512 private CompValu GenerateFromRValList(TokenRValList rValList) 4994 private CompValu GenerateFromRValList(TokenRValList rValList)
5513 { 4995 {
5514 /* 4996 // Compute all element values and remember where we put them.
5515 * Compute all element values and remember where we put them. 4997 // Do it right-to-left as customary for LSL scripts.
5516 * Do it right-to-left as customary for LSL scripts.
5517 */
5518 int i = 0; 4998 int i = 0;
5519 TokenRVal lastRVal = null; 4999 TokenRVal lastRVal = null;
5520 for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) 5000 for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken)
@@ -5529,43 +5009,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5529 vals[--i] = GenerateFromRVal(val); 5009 vals[--i] = GenerateFromRVal(val);
5530 } 5010 }
5531 5011
5532 /* 5012 // This is the temp that will hold the created list.
5533 * This is the temp that will hold the created list.
5534 */
5535 CompValuTemp newList = new CompValuTemp(new TokenTypeList(rValList.rVal), this); 5013 CompValuTemp newList = new CompValuTemp(new TokenTypeList(rValList.rVal), this);
5536 5014
5537 /* 5015 // Create a temp object[] array to hold all the initial values.
5538 * Create a temp object[] array to hold all the initial values.
5539 */
5540 ilGen.Emit(rValList, OpCodes.Ldc_I4, rValList.nItems); 5016 ilGen.Emit(rValList, OpCodes.Ldc_I4, rValList.nItems);
5541 ilGen.Emit(rValList, OpCodes.Newarr, typeof(object)); 5017 ilGen.Emit(rValList, OpCodes.Newarr, typeof(object));
5542 5018
5543 /* 5019 // Populate the array.
5544 * Populate the array.
5545 */
5546 i = 0; 5020 i = 0;
5547 for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) 5021 for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken)
5548 { 5022 {
5549 5023
5550 /* 5024 // Get pointer to temp array object.
5551 * Get pointer to temp array object.
5552 */
5553 ilGen.Emit(rValList, OpCodes.Dup); 5025 ilGen.Emit(rValList, OpCodes.Dup);
5554 5026
5555 /* 5027 // Get index in that array.
5556 * Get index in that array.
5557 */
5558 ilGen.Emit(rValList, OpCodes.Ldc_I4, i); 5028 ilGen.Emit(rValList, OpCodes.Ldc_I4, i);
5559 5029
5560 /* 5030 // Store initialization value in array location.
5561 * Store initialization value in array location. 5031 // However, floats and ints need to be converted to LSL_Float and LSL_Integer,
5562 * However, floats and ints need to be converted to LSL_Float and LSL_Integer, 5032 // or things like llSetPayPrice() will puque when they try to cast the elements
5563 * or things like llSetPayPrice() will puque when they try to cast the elements 5033 // to LSL_Float or LSL_Integer. Likewise with string/LSL_String.
5564 * to LSL_Float or LSL_Integer. Likewise with string/LSL_String. 5034 //
5565 * 5035 // Maybe it's already LSL-boxed so we don't do anything with it except make sure
5566 * Maybe it's already LSL-boxed so we don't do anything with it except make sure 5036 // it is an object, not a struct.
5567 * it is an object, not a struct.
5568 */
5569 CompValu eRVal = vals[i++]; 5037 CompValu eRVal = vals[i++];
5570 eRVal.PushVal(this, val); 5038 eRVal.PushVal(this, val);
5571 if(eRVal.type.ToLSLWrapType() == null) 5039 if(eRVal.type.ToLSLWrapType() == null)
@@ -5599,9 +5067,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5599 ilGen.Emit(val, OpCodes.Stelem, typeof(object)); 5067 ilGen.Emit(val, OpCodes.Stelem, typeof(object));
5600 } 5068 }
5601 5069
5602 /* 5070 // Create new list object from temp initial value array (whose ref is still on the stack).
5603 * Create new list object from temp initial value array (whose ref is still on the stack).
5604 */
5605 ilGen.Emit(rValList, OpCodes.Newobj, lslListConstructorInfo); 5071 ilGen.Emit(rValList, OpCodes.Newobj, lslListConstructorInfo);
5606 newList.Pop(this, rValList); 5072 newList.Pop(this, rValList);
5607 return newList; 5073 return newList;
@@ -5717,44 +5183,31 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5717 { 5183 {
5718 CompValu initValue = null; 5184 CompValu initValue = null;
5719 5185
5720 /* 5186 // If it is a sublist, process it.
5721 * If it is a sublist, process it. 5187 // If we don't have enough subscripts yet, hopefully that sublist will have enough.
5722 * If we don't have enough subscripts yet, hopefully that sublist will have enough. 5188 // If we already have enough subscripts, then that sublist can be for an element of this supposedly jagged array.
5723 * If we already have enough subscripts, then that sublist can be for an element of this supposedly jagged array.
5724 */
5725 if(val is TokenList) 5189 if(val is TokenList)
5726 { 5190 {
5727 TokenList sublist = (TokenList)val; 5191 TokenList sublist = (TokenList)val;
5728 if(dimNo + 1 < rank) 5192 if(dimNo + 1 < rank)
5729 { 5193 {
5730 5194 // We don't have enough subscripts yet, hopefully the sublist has the rest.
5731 /*
5732 * We don't have enough subscripts yet, hopefully the sublist has the rest.
5733 */
5734 FillInInitVals(array, setMeth, subscripts, dimNo + 1, rank, sublist, eleType); 5195 FillInInitVals(array, setMeth, subscripts, dimNo + 1, rank, sublist, eleType);
5735 } 5196 }
5736 else if((eleType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)eleType).decl.arrayOfType == null)) 5197 else if((eleType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)eleType).decl.arrayOfType == null))
5737 { 5198 {
5738 5199 // If we aren't a jagged array either, we can't do anything with the sublist.
5739 /*
5740 * If we aren't a jagged array either, we can't do anything with the sublist.
5741 */
5742 ErrorMsg(val, "too many brace levels"); 5200 ErrorMsg(val, "too many brace levels");
5743 } 5201 }
5744 else 5202 else
5745 { 5203 {
5746 5204 // We are a jagged array, so malloc a subarray and initialize it with the sublist.
5747 /* 5205 // Then we can use that subarray to fill this array's element.
5748 * We are a jagged array, so malloc a subarray and initialize it with the sublist.
5749 * Then we can use that subarray to fill this array's element.
5750 */
5751 initValue = MallocAndInitArray(eleType, sublist); 5206 initValue = MallocAndInitArray(eleType, sublist);
5752 } 5207 }
5753 } 5208 }
5754 5209
5755 /* 5210 // If it is a value expression, then output code to compute the value.
5756 * If it is a value expression, then output code to compute the value.
5757 */
5758 if(val is TokenRVal) 5211 if(val is TokenRVal)
5759 { 5212 {
5760 if(dimNo + 1 < rank) 5213 if(dimNo + 1 < rank)
@@ -5767,9 +5220,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5767 } 5220 }
5768 } 5221 }
5769 5222
5770 /* 5223 // If there is an initValue, output "array.Set (subscript[0], subscript[1], ..., initValue)"
5771 * If there is an initValue, output "array.Set (subscript[0], subscript[1], ..., initValue)"
5772 */
5773 if(initValue != null) 5224 if(initValue != null)
5774 { 5225 {
5775 array.PushVal(this, val); 5226 array.PushVal(this, val);
@@ -5781,9 +5232,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5781 ilGen.Emit(val, OpCodes.Call, setMeth.ilGen); 5232 ilGen.Emit(val, OpCodes.Call, setMeth.ilGen);
5782 } 5233 }
5783 5234
5784 /* 5235 // That subscript is processed one way or another, on to the next.
5785 * That subscript is processed one way or another, on to the next.
5786 */
5787 subscripts[dimNo]++; 5236 subscripts[dimNo]++;
5788 } 5237 }
5789 } 5238 }
@@ -5894,19 +5343,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5894 return new CompValuVoid(type); 5343 return new CompValuVoid(type);
5895 } 5344 }
5896 5345
5897 /* 5346 // Default for 'object' type is 'undef'.
5898 * Default for 'object' type is 'undef'. 5347 // Likewise for script-defined classes and interfaces.
5899 * Likewise for script-defined classes and interfaces.
5900 */
5901 if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeDelegate) || 5348 if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeDelegate) ||
5902 (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) 5349 (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc))
5903 { 5350 {
5904 return new CompValuNull(type); 5351 return new CompValuNull(type);
5905 } 5352 }
5906 5353
5907 /* 5354 // array and list
5908 * array and list
5909 */
5910 CompValuTemp temp = new CompValuTemp(type, this); 5355 CompValuTemp temp = new CompValuTemp(type, this);
5911 PushDefaultValue(type); 5356 PushDefaultValue(type);
5912 temp.Pop(this, rValInitDef, type); 5357 temp.Pop(this, rValInitDef, type);
@@ -5918,14 +5363,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5918 */ 5363 */
5919 private CompValu GenerateFromRValIsType(TokenRValIsType rValIsType) 5364 private CompValu GenerateFromRValIsType(TokenRValIsType rValIsType)
5920 { 5365 {
5921 /* 5366 // Expression we want to know the type of.
5922 * Expression we want to know the type of.
5923 */
5924 CompValu val = GenerateFromRVal(rValIsType.rValExp); 5367 CompValu val = GenerateFromRVal(rValIsType.rValExp);
5925 5368
5926 /* 5369 // Pass it in to top-level type expression decoder.
5927 * Pass it in to top-level type expression decoder.
5928 */
5929 return GenerateFromTypeExp(val, rValIsType.typeExp); 5370 return GenerateFromTypeExp(val, rValIsType.typeExp);
5930 } 5371 }
5931 5372
@@ -6062,28 +5503,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6062 return; 5503 return;
6063 } 5504 }
6064 5505
6065 /* 5506 // Default for 'object' type is 'undef'.
6066 * Default for 'object' type is 'undef'. 5507 // Likewise for script-defined classes and interfaces.
6067 * Likewise for script-defined classes and interfaces.
6068 */
6069 if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) 5508 if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc))
6070 { 5509 {
6071 ilGen.Emit(type, OpCodes.Ldnull); 5510 ilGen.Emit(type, OpCodes.Ldnull);
6072 return; 5511 return;
6073 } 5512 }
6074 5513
6075 /* 5514 // Void is pushed as the default return value of a void function.
6076 * Void is pushed as the default return value of a void function. 5515 // So just push nothing as expected of void functions.
6077 * So just push nothing as expected of void functions.
6078 */
6079 if(type is TokenTypeVoid) 5516 if(type is TokenTypeVoid)
6080 { 5517 {
6081 return; 5518 return;
6082 } 5519 }
6083 5520
6084 /* 5521 // Default for 'delegate' type is 'undef'.
6085 * Default for 'delegate' type is 'undef'.
6086 */
6087 if(type is TokenTypeSDTypeDelegate) 5522 if(type is TokenTypeSDTypeDelegate)
6088 { 5523 {
6089 ilGen.Emit(type, OpCodes.Ldnull); 5524 ilGen.Emit(type, OpCodes.Ldnull);
@@ -6186,16 +5621,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6186 */ 5621 */
6187 private static VarDict CreateLegalEventHandlers() 5622 private static VarDict CreateLegalEventHandlers()
6188 { 5623 {
6189 /* 5624 // Get handler prototypes with full argument lists.
6190 * Get handler prototypes with full argument lists.
6191 */
6192 VarDict leh = new InternalFuncDict(typeof(IEventHandlers), false); 5625 VarDict leh = new InternalFuncDict(typeof(IEventHandlers), false);
6193 5626
6194 /* 5627 // We want the scripts to be able to declare their handlers with
6195 * We want the scripts to be able to declare their handlers with 5628 // fewer arguments than the full argument lists. So define additional
6196 * fewer arguments than the full argument lists. So define additional 5629 // prototypes with fewer arguments.
6197 * prototypes with fewer arguments.
6198 */
6199 TokenDeclVar[] fullArgProtos = new TokenDeclVar[leh.Count]; 5630 TokenDeclVar[] fullArgProtos = new TokenDeclVar[leh.Count];
6200 int i = 0; 5631 int i = 0;
6201 foreach(TokenDeclVar fap in leh) 5632 foreach(TokenDeclVar fap in leh)
@@ -6283,9 +5714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6283 */ 5714 */
6284 private CompValu UnOpGenerate(CompValu inRVal, Token opcode) 5715 private CompValu UnOpGenerate(CompValu inRVal, Token opcode)
6285 { 5716 {
6286 /* 5717 // - Negate
6287 * - Negate
6288 */
6289 if(opcode is TokenKwSub) 5718 if(opcode is TokenKwSub)
6290 { 5719 {
6291 if(inRVal.type is TokenTypeFloat) 5720 if(inRVal.type is TokenTypeFloat)
@@ -6324,9 +5753,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6324 return inRVal; 5753 return inRVal;
6325 } 5754 }
6326 5755
6327 /* 5756 // ~ Complement (bitwise integer)
6328 * ~ Complement (bitwise integer)
6329 */
6330 if(opcode is TokenKwTilde) 5757 if(opcode is TokenKwTilde)
6331 { 5758 {
6332 if(inRVal.type is TokenTypeInt) 5759 if(inRVal.type is TokenTypeInt)
@@ -6341,13 +5768,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6341 return inRVal; 5768 return inRVal;
6342 } 5769 }
6343 5770
6344 /* 5771 // ! Not (boolean)
6345 * ! Not (boolean) 5772 //
6346 * 5773 // We stuff the 0/1 result in an int because I've seen x+!y in scripts
6347 * We stuff the 0/1 result in an int because I've seen x+!y in scripts 5774 // and we don't want to have to create tables to handle int+bool and
6348 * and we don't want to have to create tables to handle int+bool and 5775 // everything like that.
6349 * everything like that.
6350 */
6351 if(opcode is TokenKwExclam) 5776 if(opcode is TokenKwExclam)
6352 { 5777 {
6353 CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); 5778 CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this);
@@ -6367,9 +5792,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6367 */ 5792 */
6368 private TokenRVal LookupInitConstants(TokenRVal rVal, ref bool didOne) 5793 private TokenRVal LookupInitConstants(TokenRVal rVal, ref bool didOne)
6369 { 5794 {
6370 /* 5795 // If it is a static field of a script-defined type, look it up and hopefully we find a constant there.
6371 * If it is a static field of a script-defined type, look it up and hopefully we find a constant there.
6372 */
6373 TokenDeclVar gblVar; 5796 TokenDeclVar gblVar;
6374 if(rVal is TokenLValSField) 5797 if(rVal is TokenLValSField)
6375 { 5798 {
@@ -6390,17 +5813,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6390 return rVal; 5813 return rVal;
6391 } 5814 }
6392 5815
6393 /* 5816 // Only other thing we handle is stand-alone names.
6394 * Only other thing we handle is stand-alone names.
6395 */
6396 if(!(rVal is TokenLValName)) 5817 if(!(rVal is TokenLValName))
6397 return rVal; 5818 return rVal;
6398 string name = ((TokenLValName)rVal).name.val; 5819 string name = ((TokenLValName)rVal).name.val;
6399 5820
6400 /* 5821 // If we are doing the initializations for a script-defined type,
6401 * If we are doing the initializations for a script-defined type, 5822 // look for the constant among the fields for that type.
6402 * look for the constant among the fields for that type.
6403 */
6404 if(currentSDTClass != null) 5823 if(currentSDTClass != null)
6405 { 5824 {
6406 gblVar = currentSDTClass.members.FindExact(name, null); 5825 gblVar = currentSDTClass.members.FindExact(name, null);
@@ -6415,11 +5834,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6415 } 5834 }
6416 } 5835 }
6417 5836
6418 /* 5837 // Look it up as a script-defined global variable.
6419 * Look it up as a script-defined global variable. 5838 // Then if the variable is defined as a constant and has a constant value,
6420 * Then if the variable is defined as a constant and has a constant value, 5839 // we are successful. If it is defined as something else, return failure.
6421 * we are successful. If it is defined as something else, return failure.
6422 */
6423 gblVar = tokenScript.variablesStack.FindExact(name, null); 5840 gblVar = tokenScript.variablesStack.FindExact(name, null);
6424 if(gblVar != null) 5841 if(gblVar != null)
6425 { 5842 {
@@ -6431,9 +5848,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6431 return rVal; 5848 return rVal;
6432 } 5849 }
6433 5850
6434 /* 5851 // Maybe it is a built-in symbolic constant.
6435 * Maybe it is a built-in symbolic constant.
6436 */
6437 ScriptConst scriptConst = ScriptConst.Lookup(name); 5852 ScriptConst scriptConst = ScriptConst.Lookup(name);
6438 if(scriptConst != null) 5853 if(scriptConst != null)
6439 { 5854 {
@@ -6445,9 +5860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6445 } 5860 }
6446 } 5861 }
6447 5862
6448 /* 5863 // Don't know what it is, return failure.
6449 * Don't know what it is, return failure.
6450 */
6451 return rVal; 5864 return rVal;
6452 } 5865 }
6453 5866
@@ -6457,9 +5870,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6457 */ 5870 */
6458 private TokenRVal LookupBodyConstants(TokenRVal rVal, ref bool didOne) 5871 private TokenRVal LookupBodyConstants(TokenRVal rVal, ref bool didOne)
6459 { 5872 {
6460 /* 5873 // If it is a static field of a script-defined type, look it up and hopefully we find a constant there.
6461 * If it is a static field of a script-defined type, look it up and hopefully we find a constant there.
6462 */
6463 TokenDeclVar gblVar; 5874 TokenDeclVar gblVar;
6464 if(rVal is TokenLValSField) 5875 if(rVal is TokenLValSField)
6465 { 5876 {
@@ -6477,17 +5888,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6477 return rVal; 5888 return rVal;
6478 } 5889 }
6479 5890
6480 /* 5891 // Only other thing we handle is stand-alone names.
6481 * Only other thing we handle is stand-alone names.
6482 */
6483 if(!(rVal is TokenLValName)) 5892 if(!(rVal is TokenLValName))
6484 return rVal; 5893 return rVal;
6485 string name = ((TokenLValName)rVal).name.val; 5894 string name = ((TokenLValName)rVal).name.val;
6486 5895
6487 /* 5896 // Scan through the variable stack and hopefully we find a constant there.
6488 * Scan through the variable stack and hopefully we find a constant there. 5897 // But we stop as soon as we get a match because that's what the script is referring to.
6489 * But we stop as soon as we get a match because that's what the script is referring to.
6490 */
6491 CompValu val; 5898 CompValu val;
6492 for(VarDict vars = ((TokenLValName)rVal).stack; vars != null; vars = vars.outerVarDict) 5899 for(VarDict vars = ((TokenLValName)rVal).stack; vars != null; vars = vars.outerVarDict)
6493 { 5900 {
@@ -6513,9 +5920,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6513 } 5920 }
6514 } 5921 }
6515 5922
6516 /* 5923 // Maybe it is a built-in symbolic constant.
6517 * Maybe it is a built-in symbolic constant.
6518 */
6519 ScriptConst scriptConst = ScriptConst.Lookup(name); 5924 ScriptConst scriptConst = ScriptConst.Lookup(name);
6520 if(scriptConst != null) 5925 if(scriptConst != null)
6521 { 5926 {
@@ -6523,15 +5928,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6523 goto foundit; 5928 goto foundit;
6524 } 5929 }
6525 5930
6526 /* 5931 // Don't know what it is, return failure.
6527 * Don't know what it is, return failure.
6528 */
6529 return rVal; 5932 return rVal;
6530 5933
6531 /* 5934 // Found a CompValu. If it's a simple constant, then use it.
6532 * Found a CompValu. If it's a simple constant, then use it. 5935 // Otherwise tell caller we failed to simplify.
6533 * Otherwise tell caller we failed to simplify.
6534 */
6535 foundit: 5936 foundit:
6536 rVal = CompValuConst2RValConst(val, rVal); 5937 rVal = CompValuConst2RValConst(val, rVal);
6537 if(rVal is TokenRValConst) 5938 if(rVal is TokenRValConst)
@@ -6586,9 +5987,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6586 */ 5987 */
6587 public TokenDeclVar FindNamedVar(TokenLValName lValName, TokenType[] argsig) 5988 public TokenDeclVar FindNamedVar(TokenLValName lValName, TokenType[] argsig)
6588 { 5989 {
6589 /* 5990 // Look in variable stack for the given name.
6590 * Look in variable stack for the given name.
6591 */
6592 for(VarDict vars = lValName.stack; vars != null; vars = vars.outerVarDict) 5991 for(VarDict vars = lValName.stack; vars != null; vars = vars.outerVarDict)
6593 { 5992 {
6594 5993
@@ -6627,9 +6026,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6627 } 6026 }
6628 } 6027 }
6629 6028
6630 /* 6029 // If not found, try one of the built-in constants or functions.
6631 * If not found, try one of the built-in constants or functions.
6632 */
6633 if(argsig == null) 6030 if(argsig == null)
6634 { 6031 {
6635 ScriptConst scriptConst = ScriptConst.Lookup(lValName.name.val); 6032 ScriptConst scriptConst = ScriptConst.Lookup(lValName.name.val);
@@ -6670,31 +6067,28 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6670 TokenDeclVar declVar = sdtDecl.FindIFaceMember(this, name, argsig, out impl); 6067 TokenDeclVar declVar = sdtDecl.FindIFaceMember(this, name, argsig, out impl);
6671 if((declVar != null) && (impl != sdtDecl)) 6068 if((declVar != null) && (impl != sdtDecl))
6672 { 6069 {
6673 6070 // Accessing a method or propterty of another interface that the primary interface says it implements.
6674 /* 6071 // In this case, we have to cast from the primary interface to that secondary interface.
6675 * Accessing a method or propterty of another interface that the primary interface says it implements. 6072 //
6676 * In this case, we have to cast from the primary interface to that secondary interface. 6073 // interface IEnumerable {
6677 * 6074 // IEnumerator GetEnumerator ();
6678 * interface IEnumerable { 6075 // }
6679 * IEnumerator GetEnumerator (); 6076 // interface ICountable : IEnumerable {
6680 * } 6077 // integer GetCount ();
6681 * interface ICountable : IEnumerable { 6078 // }
6682 * integer GetCount (); 6079 // class List : ICountable {
6683 * } 6080 // public GetCount () : ICountable { ... }
6684 * class List : ICountable { 6081 // public GetEnumerator () : IEnumerable { ... }
6685 * public GetCount () : ICountable { ... } 6082 // }
6686 * public GetEnumerator () : IEnumerable { ... } 6083 //
6687 * } 6084 // ICountable aList = new List ();
6688 * 6085 // IEnumerator anEnumer = aList.GetEnumerator (); << we are here
6689 * ICountable aList = new List (); 6086 // << baseRVal = aList
6690 * IEnumerator anEnumer = aList.GetEnumerator (); << we are here 6087 // << sdtDecl = ICountable
6691 * << baseRVal = aList 6088 // << impl = IEnumerable
6692 * << sdtDecl = ICountable 6089 // << name = GetEnumerator
6693 * << impl = IEnumerable 6090 // << argsig = ()
6694 * << name = GetEnumerator 6091 // So we have to cast aList from ICountable to IEnumerable.
6695 * << argsig = ()
6696 * So we have to cast aList from ICountable to IEnumerable.
6697 */
6698 6092
6699 // make type token for the secondary interface type 6093 // make type token for the secondary interface type
6700 TokenType subIntfType = impl.MakeRefToken(name); 6094 TokenType subIntfType = impl.MakeRefToken(name);
@@ -6799,19 +6193,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6799 TokenDeclSDType definedBy = var.sdtClass; 6193 TokenDeclSDType definedBy = var.sdtClass;
6800 TokenDeclSDType accessedBy = curDeclFunc.sdtClass; 6194 TokenDeclSDType accessedBy = curDeclFunc.sdtClass;
6801 6195
6802 /*******************************\ 6196 //*******************************
6803 * Check member-level access * 6197 // Check member-level access
6804 \*******************************/ 6198 //*******************************
6805 6199
6806 /* 6200 // Note that if accessedBy is null, ie, accessing from global function (or event handlers),
6807 * Note that if accessedBy is null, ie, accessing from global function (or event handlers), 6201 // anything tagged as SDT_PRIVATE or SDT_PROTECTED will fail.
6808 * anything tagged as SDT_PRIVATE or SDT_PROTECTED will fail.
6809 */
6810 6202
6811 /* 6203 // Private means accessed by the class that defined the member or accessed by a nested class
6812 * Private means accessed by the class that defined the member or accessed by a nested class 6204 // of the class that defined the member.
6813 * of the class that defined the member.
6814 */
6815 if((var.sdtFlags & ScriptReduce.SDT_PRIVATE) != 0) 6205 if((var.sdtFlags & ScriptReduce.SDT_PRIVATE) != 0)
6816 { 6206 {
6817 for(nested = accessedBy; nested != null; nested = nested.outerSDType) 6207 for(nested = accessedBy; nested != null; nested = nested.outerSDType)
@@ -6823,12 +6213,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6823 return; 6213 return;
6824 } 6214 }
6825 6215
6826 /* 6216 // Protected means:
6827 * Protected means: 6217 // If being accessed by an inner class, the inner class has access to it if the inner class derives
6828 * If being accessed by an inner class, the inner class has access to it if the inner class derives 6218 // from the declaring class. It also has access to it if an outer class derives from the declaring
6829 * from the declaring class. It also has access to it if an outer class derives from the declaring 6219 // class.
6830 * class.
6831 */
6832 if((var.sdtFlags & ScriptReduce.SDT_PROTECTED) != 0) 6220 if((var.sdtFlags & ScriptReduce.SDT_PROTECTED) != 0)
6833 { 6221 {
6834 for(nested = accessedBy; nested != null; nested = nested.outerSDType) 6222 for(nested = accessedBy; nested != null; nested = nested.outerSDType)
@@ -6844,26 +6232,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6844 } 6232 }
6845 acc1ok: 6233 acc1ok:
6846 6234
6847 /******************************\ 6235 //******************************
6848 * Check class-level access * 6236 // Check class-level access
6849 \******************************/ 6237 //******************************
6850 6238
6851 /* 6239 // If being accessed by same or inner class than where defined, it is ok.
6852 * If being accessed by same or inner class than where defined, it is ok. 6240 //
6853 * 6241 // class DefiningClass {
6854 * class DefiningClass { 6242 // varBeingAccessed;
6855 * varBeingAccessed; 6243 // .
6856 * . 6244 // .
6857 * . 6245 // .
6858 * . 6246 // class AccessingClass {
6859 * class AccessingClass { 6247 // functionDoingAccess() { }
6860 * functionDoingAccess() { } 6248 // }
6861 * } 6249 // .
6862 * . 6250 // .
6863 * . 6251 // .
6864 * . 6252 // }
6865 * }
6866 */
6867 nested = accessedBy; 6253 nested = accessedBy;
6868 while(true) 6254 while(true)
6869 { 6255 {
@@ -6874,46 +6260,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6874 nested = (TokenDeclSDTypeClass)nested.outerSDType; 6260 nested = (TokenDeclSDTypeClass)nested.outerSDType;
6875 } 6261 }
6876 6262
6877 /* 6263 // It is being accessed by an outer class than where defined,
6878 * It is being accessed by an outer class than where defined, 6264 // check for a 'private' or 'protected' class tag that blocks.
6879 * check for a 'private' or 'protected' class tag that blocks.
6880 */
6881 do 6265 do
6882 { 6266 {
6883 6267 // If the field's class is defined directly inside the accessing class,
6884 /* 6268 // access is allowed regardless of class-level private or protected tags.
6885 * If the field's class is defined directly inside the accessing class, 6269 //
6886 * access is allowed regardless of class-level private or protected tags. 6270 // class AccessingClass {
6887 * 6271 // functionDoingAccess() { }
6888 * class AccessingClass { 6272 // class DefiningClass {
6889 * functionDoingAccess() { } 6273 // varBeingAccessed;
6890 * class DefiningClass { 6274 // }
6891 * varBeingAccessed; 6275 // }
6892 * }
6893 * }
6894 */
6895 if(definedBy.outerSDType == accessedBy) 6276 if(definedBy.outerSDType == accessedBy)
6896 return; 6277 return;
6897 6278
6898 /* 6279 // If the field's class is defined two or more levels inside the accessing class,
6899 * If the field's class is defined two or more levels inside the accessing class, 6280 // access is denied if the defining class is tagged private.
6900 * access is denied if the defining class is tagged private. 6281 //
6901 * 6282 // class AccessingClass {
6902 * class AccessingClass { 6283 // functionDoingAccess() { }
6903 * functionDoingAccess() { } 6284 // .
6904 * . 6285 // .
6905 * . 6286 // .
6906 * . 6287 // class IntermediateClass {
6907 * class IntermediateClass { 6288 // private class DefiningClass {
6908 * private class DefiningClass { 6289 // varBeingAccessed;
6909 * varBeingAccessed; 6290 // }
6910 * } 6291 // }
6911 * } 6292 // .
6912 * . 6293 // .
6913 * . 6294 // .
6914 * . 6295 // }
6915 * }
6916 */
6917 if((definedBy.accessLevel & ScriptReduce.SDT_PRIVATE) != 0) 6296 if((definedBy.accessLevel & ScriptReduce.SDT_PRIVATE) != 0)
6918 { 6297 {
6919 ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName + 6298 ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName +
@@ -6921,10 +6300,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6921 return; 6300 return;
6922 } 6301 }
6923 6302
6924 /* 6303 // Likewise, if DefiningClass is tagged protected, the AccessingClass must derive from the
6925 * Likewise, if DefiningClass is tagged protected, the AccessingClass must derive from the 6304 // IntermediateClass or access is denied.
6926 * IntermediateClass or access is denied.
6927 */
6928 if((definedBy.accessLevel & ScriptReduce.SDT_PROTECTED) != 0) 6305 if((definedBy.accessLevel & ScriptReduce.SDT_PROTECTED) != 0)
6929 { 6306 {
6930 for(TokenDeclSDType extends = accessedBy; extends != definedBy.outerSDType; extends = extends.extends) 6307 for(TokenDeclSDType extends = accessedBy; extends != definedBy.outerSDType; extends = extends.extends)
@@ -6938,9 +6315,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6938 } 6315 }
6939 } 6316 }
6940 6317
6941 /* 6318 // Check next outer level.
6942 * Check next outer level.
6943 */
6944 definedBy = definedBy.outerSDType; 6319 definedBy = definedBy.outerSDType;
6945 } while(definedBy != null); 6320 } while(definedBy != null);
6946 } 6321 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
index 4a57823..88cd6c1 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs
@@ -511,20 +511,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
511 } 511 }
512 public override bool MoveNext() 512 public override bool MoveNext()
513 { 513 {
514 /* 514 // First off, return any targets the instruction can come up with.
515 * First off, return any targets the instruction can come up with.
516 */
517 if(realEnumerator.MoveNext()) 515 if(realEnumerator.MoveNext())
518 { 516 {
519 nn = realEnumerator.Current; 517 nn = realEnumerator.Current;
520 return true; 518 return true;
521 } 519 }
522 520
523 /* 521 // Then if this instruction is in a try section, say this instruction
524 * Then if this instruction is in a try section, say this instruction 522 // can potentially branch to the beginning of the corresponding
525 * can potentially branch to the beginning of the corresponding 523 // catch/finally.
526 * catch/finally.
527 */
528 if((index == 0) && (gn.tryBlock != null)) 524 if((index == 0) && (gn.tryBlock != null))
529 { 525 {
530 index++; 526 index++;
@@ -532,9 +528,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
532 return true; 528 return true;
533 } 529 }
534 530
535 /* 531 // That's all we can do.
536 * That's all we can do.
537 */
538 nn = null; 532 nn = null;
539 return false; 533 return false;
540 } 534 }
@@ -1875,9 +1869,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1875 } 1869 }
1876 public override bool MoveNext() 1870 public override bool MoveNext()
1877 { 1871 {
1878 /* 1872 // Return next from list of switch case labels.
1879 * Return next from list of switch case labels.
1880 */
1881 while(index < gn.myLabels.Length) 1873 while(index < gn.myLabels.Length)
1882 { 1874 {
1883 nn = gn.myLabels[index++].whereAmI; 1875 nn = gn.myLabels[index++].whereAmI;
@@ -1885,9 +1877,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1885 return true; 1877 return true;
1886 } 1878 }
1887 1879
1888 /* 1880 // If all ran out, the switch instruction falls through.
1889 * If all ran out, the switch instruction falls through.
1890 */
1891 if(index == gn.myLabels.Length) 1881 if(index == gn.myLabels.Length)
1892 { 1882 {
1893 index++; 1883 index++;
@@ -1895,9 +1885,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1895 return true; 1885 return true;
1896 } 1886 }
1897 1887
1898 /* 1888 // Even ran out of that, say there's nothing more.
1899 * Even ran out of that, say there's nothing more.
1900 */
1901 nn = null; 1889 nn = null;
1902 return false; 1890 return false;
1903 } 1891 }
@@ -2527,10 +2515,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2527 if(curExcBlock != null) 2515 if(curExcBlock != null)
2528 throw new Exception("exception block still open"); 2516 throw new Exception("exception block still open");
2529 2517
2530 /* 2518 // If an instruction says it doesn't fall through, remove all instructions to
2531 * If an instruction says it doesn't fall through, remove all instructions to 2519 // the end of the block.
2532 * the end of the block.
2533 */
2534 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2520 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2535 { 2521 {
2536 if(!gn.CanFallThrough()) 2522 if(!gn.CanFallThrough())
@@ -2547,12 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2547 } 2533 }
2548 } 2534 }
2549 2535
2550 /* 2536 // Scan for OpCodes.Leave instructions.
2551 * Scan for OpCodes.Leave instructions. 2537 // For each found, its target for flow analysis purposes is the beginning of the corresponding
2552 * For each found, its target for flow analysis purposes is the beginning of the corresponding 2538 // finally block. And the end of the finally block gets a conditional branch target of the
2553 * finally block. And the end of the finally block gets a conditional branch target of the 2539 // leave instruction's target. A leave instruction can unwind zero or more finally blocks.
2554 * leave instruction's target. A leave instruction can unwind zero or more finally blocks.
2555 */
2556 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2540 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2557 { 2541 {
2558 if(gn is GraphNodeEmitLabelLeave) 2542 if(gn is GraphNodeEmitLabelLeave)
@@ -2562,12 +2546,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2562 GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target 2546 GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target
2563 (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound 2547 (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound
2564 2548
2565 /* 2549 // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s.
2566 * Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. 2550 // The leave instruction unconditionally branches to the beginning of the innermost one found.
2567 * The leave instruction unconditionally branches to the beginning of the innermost one found. 2551 // The end of the last one found conditionally branches to the leave instruction's target.
2568 * The end of the last one found conditionally branches to the leave instruction's target. 2552 // If none found, the leave is a simple unconditional branch to its target.
2569 * If none found, the leave is a simple unconditional branch to its target.
2570 */
2571 GraphNodeBeginFinallyBlock innerFinallyBlock = null; 2553 GraphNodeBeginFinallyBlock innerFinallyBlock = null;
2572 for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; 2554 for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock;
2573 tryBlock != leaveTargetsTryBlock; 2555 tryBlock != leaveTargetsTryBlock;
@@ -2586,10 +2568,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2586 } 2568 }
2587 } 2569 }
2588 2570
2589 /* 2571 // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction.
2590 * The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. 2572 // In the case of no finallies being unwound, the leave is just a simple unconditional branch.
2591 * In the case of no finallies being unwound, the leave is just a simple unconditional branch.
2592 */
2593 if(innerFinallyBlock == null) 2573 if(innerFinallyBlock == null)
2594 { 2574 {
2595 leaveInstr.unwindTo = leaveTarget; 2575 leaveInstr.unwindTo = leaveTarget;
@@ -2601,10 +2581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2601 } 2581 }
2602 } 2582 }
2603 2583
2604 /* 2584 // See which variables a particular block reads before writing.
2605 * See which variables a particular block reads before writing. 2585 // This just considers the block itself and nothing that it branches to or fallsthru to.
2606 * This just considers the block itself and nothing that it branches to or fallsthru to.
2607 */
2608 GraphNodeBlock currentBlock = null; 2586 GraphNodeBlock currentBlock = null;
2609 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2587 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2610 { 2588 {
@@ -2626,13 +2604,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2626 } 2604 }
2627 } 2605 }
2628 2606
2629 /* 2607 // For every block we branch to, add that blocks readables to our list of readables,
2630 * For every block we branch to, add that blocks readables to our list of readables, 2608 // because we need to have those values valid on entry to our block. But if we write the
2631 * because we need to have those values valid on entry to our block. But if we write the 2609 // variable before we can possibly branch to that block, then we don't need to have it valid
2632 * variable before we can possibly branch to that block, then we don't need to have it valid 2610 // on entry to our block. So basically it looks like the branch instruction is reading
2633 * on entry to our block. So basically it looks like the branch instruction is reading 2611 // everything required by any blocks it can branch to.
2634 * everything required by any blocks it can branch to.
2635 */
2636 do 2612 do
2637 { 2613 {
2638 this.resolvedSomething = false; 2614 this.resolvedSomething = false;
@@ -2640,17 +2616,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2640 this.ResolveBlock((GraphNodeBlock)firstLin); 2616 this.ResolveBlock((GraphNodeBlock)firstLin);
2641 } while(this.resolvedSomething); 2617 } while(this.resolvedSomething);
2642 2618
2643 /* 2619 // Repeat the cutting loops as long as we keep finding stuff.
2644 * Repeat the cutting loops as long as we keep finding stuff.
2645 */
2646 bool didSomething; 2620 bool didSomething;
2647 do 2621 do
2648 { 2622 {
2649 didSomething = false; 2623 didSomething = false;
2650 2624
2651 /* 2625 // Strip out ldc.i4.1/xor/ldc.i4.1/xor
2652 * Strip out ldc.i4.1/xor/ldc.i4.1/xor
2653 */
2654 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2626 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2655 { 2627 {
2656 if(!(gn is GraphNodeEmit)) 2628 if(!(gn is GraphNodeEmit))
@@ -2678,9 +2650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2678 didSomething = true; 2650 didSomething = true;
2679 } 2651 }
2680 2652
2681 /* 2653 // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false}
2682 * Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false}
2683 */
2684 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2654 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2685 { 2655 {
2686 if(!(gn is GraphNodeEmit)) 2656 if(!(gn is GraphNodeEmit))
@@ -2711,9 +2681,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2711 didSomething = true; 2681 didSomething = true;
2712 } 2682 }
2713 2683
2714 /* 2684 // Replace c{cond}/br{false,true} -> b{!,}{cond}
2715 * Replace c{cond}/br{false,true} -> b{!,}{cond}
2716 */
2717 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2685 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2718 { 2686 {
2719 if(!(gn is GraphNodeEmit)) 2687 if(!(gn is GraphNodeEmit))
@@ -2746,9 +2714,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2746 didSomething = true; 2714 didSomething = true;
2747 } 2715 }
2748 2716
2749 /* 2717 // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false}
2750 * Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false}
2751 */
2752 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2718 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2753 { 2719 {
2754 if(!(gn is GraphNodeEmit)) 2720 if(!(gn is GraphNodeEmit))
@@ -2767,17 +2733,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2767 didSomething = true; 2733 didSomething = true;
2768 } 2734 }
2769 2735
2770 /* 2736 // Replace:
2771 * Replace: 2737 // ldloc v1
2772 * ldloc v1 2738 // stloc v2
2773 * stloc v2 2739 // ld<anything> except ld<anything> v2
2774 * ld<anything> except ld<anything> v2 2740 // ldloc v2
2775 * ldloc v2 2741 // ...v2 unreferenced hereafter
2776 * ...v2 unreferenced hereafter 2742 // With:
2777 * With: 2743 // ld<anything> except ld<anything> v2
2778 * ld<anything> except ld<anything> v2 2744 // ldloc v1
2779 * ldloc v1
2780 */
2781 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2745 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2782 { 2746 {
2783 2747
@@ -2833,11 +2797,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2833 didSomething = true; 2797 didSomething = true;
2834 } 2798 }
2835 2799
2836 /* 2800 // Remove all the stloc/ldloc that are back-to-back without the local
2837 * Remove all the stloc/ldloc that are back-to-back without the local 2801 // being needed afterwards. If it is needed afterwards, replace the
2838 * being needed afterwards. If it is needed afterwards, replace the 2802 // stloc/ldloc with dup/stloc.
2839 * stloc/ldloc with dup/stloc.
2840 */
2841 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2803 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2842 { 2804 {
2843 if((gn is GraphNodeEmitLocal) && 2805 if((gn is GraphNodeEmitLocal) &&
@@ -2871,10 +2833,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2871 } 2833 }
2872 } 2834 }
2873 2835
2874 /* 2836 // Remove all write-only local variables, ie, those with no ldloc[a] references.
2875 * Remove all write-only local variables, ie, those with no ldloc[a] references. 2837 // Replace any stloc instructions with pops.
2876 * Replace any stloc instructions with pops.
2877 */
2878 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2838 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2879 { 2839 {
2880 ScriptMyLocal rdlcl = gn.ReadsLocal(); 2840 ScriptMyLocal rdlcl = gn.ReadsLocal();
@@ -2900,9 +2860,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2900 } 2860 }
2901 } 2861 }
2902 2862
2903 /* 2863 // Remove any Ld<const>/Dup,Pop.
2904 * Remove any Ld<const>/Dup,Pop.
2905 */
2906 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) 2864 for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin)
2907 { 2865 {
2908 if((gn is GraphNodeEmit) && 2866 if((gn is GraphNodeEmit) &&
@@ -2921,9 +2879,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2921 } 2879 }
2922 } while(didSomething); 2880 } while(didSomething);
2923 2881
2924 /* 2882 // Dump out the results.
2925 * Dump out the results.
2926 */
2927 if(DEBUG) 2883 if(DEBUG)
2928 { 2884 {
2929 Console.WriteLine(""); 2885 Console.WriteLine("");
@@ -2982,55 +2938,39 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2982 if(currentBlock.hasBeenResolved == this.resolveSequence) 2938 if(currentBlock.hasBeenResolved == this.resolveSequence)
2983 return; 2939 return;
2984 2940
2985 /* 2941 // So we don't recurse forever on a backward branch.
2986 * So we don't recurse forever on a backward branch.
2987 */
2988 currentBlock.hasBeenResolved = this.resolveSequence; 2942 currentBlock.hasBeenResolved = this.resolveSequence;
2989 2943
2990 /* 2944 // Assume we haven't written any locals yet.
2991 * Assume we haven't written any locals yet.
2992 */
2993 List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>(); 2945 List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>();
2994 2946
2995 /* 2947 // Scan through the instructions in this block.
2996 * Scan through the instructions in this block.
2997 */
2998 for(GraphNode gn = currentBlock; gn != null;) 2948 for(GraphNode gn = currentBlock; gn != null;)
2999 { 2949 {
3000 2950
3001 /* 2951 // See if the instruction writes a local we don't know about yet.
3002 * See if the instruction writes a local we don't know about yet.
3003 */
3004 ScriptMyLocal wrlcl = gn.WritesLocal(); 2952 ScriptMyLocal wrlcl = gn.WritesLocal();
3005 if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) 2953 if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl))
3006 { 2954 {
3007 localsWrittenSoFar.Add(wrlcl); 2955 localsWrittenSoFar.Add(wrlcl);
3008 } 2956 }
3009 2957
3010 /* 2958 // Scan through all the possible next instructions after this.
3011 * Scan through all the possible next instructions after this. 2959 // Note that if we are in the first part of a try/catch/finally block,
3012 * Note that if we are in the first part of a try/catch/finally block, 2960 // every instruction conditionally branches to the beginning of the
3013 * every instruction conditionally branches to the beginning of the 2961 // second part (the catch/finally block).
3014 * second part (the catch/finally block).
3015 */
3016 GraphNode nextFallthruNode = null; 2962 GraphNode nextFallthruNode = null;
3017 foreach(GraphNode nn in gn.NextNodes) 2963 foreach(GraphNode nn in gn.NextNodes)
3018 { 2964 {
3019 if(nn is GraphNodeBlock) 2965 if(nn is GraphNodeBlock)
3020 { 2966 {
3021 2967 // Start of a block, go through all locals needed by that block on entry.
3022 /*
3023 * Start of a block, go through all locals needed by that block on entry.
3024 */
3025 GraphNodeBlock nextBlock = (GraphNodeBlock)nn; 2968 GraphNodeBlock nextBlock = (GraphNodeBlock)nn;
3026 ResolveBlock(nextBlock); 2969 ResolveBlock(nextBlock);
3027 foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) 2970 foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten)
3028 { 2971 {
3029 2972 // If this block hasn't written it by now and this block doesn't already
3030 /* 2973 // require it on entry, say this block requires it on entry.
3031 * If this block hasn't written it by now and this block doesn't already
3032 * require it on entry, say this block requires it on entry.
3033 */
3034 if(!localsWrittenSoFar.Contains(readByNextBlock) && 2974 if(!localsWrittenSoFar.Contains(readByNextBlock) &&
3035 !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) 2975 !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock))
3036 { 2976 {
@@ -3041,19 +2981,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3041 } 2981 }
3042 else 2982 else
3043 { 2983 {
3044 2984 // Not start of a block, should be normal fallthru instruction.
3045 /*
3046 * Not start of a block, should be normal fallthru instruction.
3047 */
3048 if(nextFallthruNode != null) 2985 if(nextFallthruNode != null)
3049 throw new Exception("more than one fallthru from " + gn.ToString()); 2986 throw new Exception("more than one fallthru from " + gn.ToString());
3050 nextFallthruNode = nn; 2987 nextFallthruNode = nn;
3051 } 2988 }
3052 } 2989 }
3053 2990
3054 /* 2991 // Process next instruction if it isn't the start of a block.
3055 * Process next instruction if it isn't the start of a block.
3056 */
3057 if(nextFallthruNode == gn) 2992 if(nextFallthruNode == gn)
3058 throw new Exception("can't fallthru to self"); 2993 throw new Exception("can't fallthru to self");
3059 gn = nextFallthruNode; 2994 gn = nextFallthruNode;
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
index 17bc3ec..675ab9a 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs
@@ -107,8 +107,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
107 return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType(); 107 return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType();
108 } 108 }
109 109
110 // if a field of an XMRInstArrays array cannot be directly written, 110 /*
111 // get the method that can write it 111 * if a field of an XMRInstArrays array cannot be directly written,
112 * get the method that can write it
113 */
112 private static MethodInfo ArrVarPopMeth(FieldInfo fi) 114 private static MethodInfo ArrVarPopMeth(FieldInfo fi)
113 { 115 {
114 if(fi.Name == "iarLists") 116 if(fi.Name == "iarLists")
@@ -120,7 +122,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
120 return null; 122 return null;
121 } 123 }
122 124
123 // emit code to push value onto stack 125 /*
126 * emit code to push value onto stack
127 */
124 public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType) 128 public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType)
125 { 129 {
126 this.PushVal(scg, errorAt, stackType, false); 130 this.PushVal(scg, errorAt, stackType, false);
@@ -133,7 +137,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
133 public abstract void PushVal(ScriptCodeGen scg, Token errorAt); 137 public abstract void PushVal(ScriptCodeGen scg, Token errorAt);
134 public abstract void PushRef(ScriptCodeGen scg, Token errorAt); 138 public abstract void PushRef(ScriptCodeGen scg, Token errorAt);
135 139
136 // emit code to pop value from stack 140 /*
141 * emit code to pop value from stack
142 */
137 public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType) 143 public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType)
138 { 144 {
139 TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); 145 TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false);
@@ -141,11 +147,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
141 } 147 }
142 public virtual void PopPre(ScriptCodeGen scg, Token errorAt) 148 public virtual void PopPre(ScriptCodeGen scg, Token errorAt)
143 { 149 {
144 } // call this before pushing value to be popped 150 }
151
152 /*
153 * call this before pushing value to be popped
154 */
145 public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped 155 public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped
146 156
147 // return true: doing a PushVal() does not involve CheckRun() 157
148 // false: otherwise 158 /*
159 * return true: doing a PushVal() does not involve CheckRun()
160 * false: otherwise
161 */
149 public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt) 162 public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt)
150 { 163 {
151 return true; 164 return true;
@@ -173,12 +186,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
173 return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig(); 186 return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig();
174 } 187 }
175 188
176 // These are used only if type is a delegate too 189 /*
177 // - but it is a real delegate pointer in a global or local variable or a field, etc 190 * These are used only if type is a delegate too
178 // ie, PushVal() pushes a delegate pointer 191 * - but it is a real delegate pointer in a global or local variable or a field, etc
179 // - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...) 192 * - ie, PushVal() pushes a delegate pointer
180 // - and CallPost() call the delegate's Invoke() method 193 * - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...)
181 // - we assume the target function is non-trivial so we always use a call label 194 * - and CallPost() call the delegate's Invoke() method
195 * - we assume the target function is non-trivial so we always use a call label
196 */
182 public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments 197 public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments
183 { 198 {
184 new ScriptCodeGen.CallLabel(scg, errorAt); 199 new ScriptCodeGen.CallLabel(scg, errorAt);
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs
index 63a6ee9..b44c4e2 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs
@@ -64,9 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
64 { 64 {
65 Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>(); 65 Dictionary<string, ScriptConst> sc = new Dictionary<string, ScriptConst>();
66 66
67 /* 67 // For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols.
68 * For every event code, define XMREVENTCODE_<eventname> and XMREVENTMASKn_<eventname> symbols.
69 */
70 for(int i = 0; i < 64; i++) 68 for(int i = 0; i < 64; i++)
71 { 69 {
72 try 70 try
@@ -87,9 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
87 catch { } 85 catch { }
88 } 86 }
89 87
90 /* 88 // Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well.
91 * Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well.
92 */
93 for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType) 89 for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType)
94 { 90 {
95 AddInterfaceConstants(sc, t.GetFields()); 91 AddInterfaceConstants(sc, t.GetFields());
@@ -132,10 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
132 Type fieldType = constField.FieldType; 128 Type fieldType = constField.FieldType;
133 CompValu cv; 129 CompValu cv;
134 130
135 /* 131 // The location of a simple number is the number itself.
136 * The location of a simple number is the number itself. 132 // Access to the value gets compiled as an ldc instruction.
137 * Access to the value gets compiled as an ldc instruction.
138 */
139 if(fieldType == typeof(double)) 133 if(fieldType == typeof(double))
140 { 134 {
141 cv = new CompValuFloat(new TokenTypeFloat(null), 135 cv = new CompValuFloat(new TokenTypeFloat(null),
@@ -152,10 +146,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
152 ((LSL_Integer)constField.GetValue(null)).value); 146 ((LSL_Integer)constField.GetValue(null)).value);
153 } 147 }
154 148
155 /* 149 // The location of a string is the string itself.
156 * The location of a string is the string itself. 150 // Access to the value gets compiled as an ldstr instruction.
157 * Access to the value gets compiled as an ldstr instruction.
158 */
159 else if(fieldType == typeof(string)) 151 else if(fieldType == typeof(string))
160 { 152 {
161 cv = new CompValuString(new TokenTypeStr(null), 153 cv = new CompValuString(new TokenTypeStr(null),
@@ -167,18 +159,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
167 (string)(LSL_String)constField.GetValue(null)); 159 (string)(LSL_String)constField.GetValue(null));
168 } 160 }
169 161
170 /* 162 // The location of everything else (objects) is the static field in the interface definition.
171 * The location of everything else (objects) is the static field in the interface definition. 163 // Access to the value gets compiled as an ldsfld instruction.
172 * Access to the value gets compiled as an ldsfld instruction.
173 */
174 else 164 else
175 { 165 {
176 cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField); 166 cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField);
177 } 167 }
178 168
179 /* 169 // Add to dictionary.
180 * Add to dictionary.
181 */
182 new ScriptConst(sc, constField.Name, cv); 170 new ScriptConst(sc, constField.Name, cv);
183 } 171 }
184 } 172 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs
index d5b08f0..24d7c3d 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs
@@ -87,9 +87,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
87 */ 87 */
88 public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter) 88 public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter)
89 { 89 {
90 /* 90 // Check version number to make sure we know how to process file contents.
91 * Check version number to make sure we know how to process file contents.
92 */
93 char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length); 91 char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length);
94 if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC) 92 if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC)
95 throw new Exception("not an XMR object file (bad magic)"); 93 throw new Exception("not an XMR object file (bad magic)");
@@ -206,14 +204,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
206 */ 204 */
207 public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs) 205 public void EndMethod(DynamicMethod method, Dictionary<int, ScriptSrcLoc> srcLocs)
208 { 206 {
209 /* 207 // Save method object code pointer.
210 * Save method object code pointer.
211 */
212 dynamicMethods.Add(method.Name, method); 208 dynamicMethods.Add(method.Name, method);
213 209
214 /* 210 // Build and sort iloffset -> source code location array.
215 * Build and sort iloffset -> source code location array.
216 */
217 int n = srcLocs.Count; 211 int n = srcLocs.Count;
218 KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n]; 212 KeyValuePair<int, ScriptSrcLoc>[] srcLocArray = new KeyValuePair<int, ScriptSrcLoc>[n];
219 n = 0; 213 n = 0;
@@ -221,9 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
221 srcLocArray[n++] = kvp; 215 srcLocArray[n++] = kvp;
222 Array.Sort(srcLocArray, endMethodWrapper); 216 Array.Sort(srcLocArray, endMethodWrapper);
223 217
224 /* 218 // Save sorted array.
225 * Save sorted array.
226 */
227 scriptSrcLocss.Add(method.Name, srcLocArray); 219 scriptSrcLocss.Add(method.Name, srcLocArray);
228 } 220 }
229 221
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs
index b87bc72..6ab0bb5 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs
@@ -121,9 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
121 this.argTypes = argTypes; 121 this.argTypes = argTypes;
122 this.objFileWriter = objFileWriter; 122 this.objFileWriter = objFileWriter;
123 123
124 /* 124 // Build list that translates system-defined types to script defined types.
125 * Build list that translates system-defined types to script defined types.
126 */
127 foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues) 125 foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues)
128 { 126 {
129 Type sys = sdt.GetSysType(); 127 Type sys = sdt.GetSysType();
@@ -131,11 +129,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
131 sdTypesRev[sys] = sdt.longName.val; 129 sdTypesRev[sys] = sdt.longName.val;
132 } 130 }
133 131
134 /* 132 // This tells the reader to call 'new DynamicMethod()' to create
135 * This tells the reader to call 'new DynamicMethod()' to create 133 // the function header. Then any forward reference calls to this
136 * the function header. Then any forward reference calls to this 134 // method will have a MethodInfo struct to call.
137 * method will have a MethodInfo struct to call.
138 */
139 objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod); 135 objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod);
140 objFileWriter.Write(methName); 136 objFileWriter.Write(methName);
141 objFileWriter.Write(GetStrFromType(retType)); 137 objFileWriter.Write(GetStrFromType(retType));
@@ -154,10 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
154 */ 150 */
155 public void BegMethod() 151 public void BegMethod()
156 { 152 {
157 /* 153 // This tells the reader to call methodInfo.GetILGenerator()
158 * This tells the reader to call methodInfo.GetILGenerator() 154 // so it can start writing CIL code for the method.
159 * so it can start writing CIL code for the method.
160 */
161 objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod); 155 objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod);
162 objFileWriter.Write(methName); 156 objFileWriter.Write(methName);
163 } 157 }
@@ -167,11 +161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
167 */ 161 */
168 public void EndMethod() 162 public void EndMethod()
169 { 163 {
170 /* 164 // This tells the reader that all code for the method has
171 * This tells the reader that all code for the method has 165 // been written and so it will typically call CreateDelegate()
172 * been written and so it will typically call CreateDelegate() 166 // to finalize the method and create an entrypoint.
173 * to finalize the method and create an entrypoint.
174 */
175 objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod); 167 objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod);
176 168
177 objFileWriter = null; 169 objFileWriter = null;
@@ -404,431 +396,385 @@ namespace OpenSim.Region.ScriptEngine.Yengine
404 396
405 while(true) 397 while(true)
406 { 398 {
407 399 // Get IL instruction offset at beginning of instruction.
408 /*
409 * Get IL instruction offset at beginning of instruction.
410 */
411 offset = 0; 400 offset = 0;
412 if((ilGen != null) && (monoGetCurrentOffset != null)) 401 if((ilGen != null) && (monoGetCurrentOffset != null))
413 { 402 {
414 offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg); 403 offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg);
415 } 404 }
416 405
417 /* 406 // Read and decode next internal format code from input file (.xmrobj file).
418 * Read and decode next internal format code from input file (.xmrobj file).
419 */
420 ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte(); 407 ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte();
421 switch(code) 408 switch(code)
422 { 409 {
423 410 // Reached end-of-file so we are all done.
424 /*
425 * Reached end-of-file so we are all done.
426 */
427 case ScriptObjWriterCode.TheEnd: 411 case ScriptObjWriterCode.TheEnd:
428 { 412 return;
429 return;
430 }
431 413
432 /* 414 // Beginning of method's contents.
433 * Beginning of method's contents. 415 // Method must have already been declared via DclMethod
434 * Method must have already been declared via DclMethod 416 // so all we need is its name to retrieve from methods[].
435 * so all we need is its name to retrieve from methods[].
436 */
437 case ScriptObjWriterCode.BegMethod: 417 case ScriptObjWriterCode.BegMethod:
438 { 418 {
439 string methName = objReader.ReadString(); 419 string methName = objReader.ReadString();
440 420
441 method = methods[methName]; 421 method = methods[methName];
442 ilGen = method.GetILGenerator(); 422 ilGen = method.GetILGenerator();
443 ilGenArg[0] = ilGen; 423 ilGenArg[0] = ilGen;
444 424
445 labels.Clear(); 425 labels.Clear();
446 locals.Clear(); 426 locals.Clear();
447 labelNames.Clear(); 427 labelNames.Clear();
448 localNames.Clear(); 428 localNames.Clear();
449 429
450 srcLocs = new Dictionary<int, ScriptSrcLoc>(); 430 srcLocs = new Dictionary<int, ScriptSrcLoc>();
451 if(objectTokens != null) 431 if(objectTokens != null)
452 objectTokens.BegMethod(method); 432 objectTokens.BegMethod(method);
453 break; 433 break;
454 } 434 }
455 435
456 /* 436 // End of method's contents (ie, an OpCodes.Ret was probably just output).
457 * End of method's contents (ie, an OpCodes.Ret was probably just output). 437 // Call the callback to tell it the method is complete, and it can do whatever
458 * Call the callback to tell it the method is complete, and it can do whatever 438 // it wants with the method.
459 * it wants with the method.
460 */
461 case ScriptObjWriterCode.EndMethod: 439 case ScriptObjWriterCode.EndMethod:
462 { 440 {
463 ilGen = null; 441 ilGen = null;
464 ilGenArg[0] = null; 442 ilGenArg[0] = null;
465 scriptObjCode.EndMethod(method, srcLocs); 443 scriptObjCode.EndMethod(method, srcLocs);
466 srcLocs = null; 444 srcLocs = null;
467 if(objectTokens != null) 445 if(objectTokens != null)
468 objectTokens.EndMethod(); 446 objectTokens.EndMethod();
469 break; 447 break;
470 } 448 }
471 449
472 /* 450 // Declare a label for branching to.
473 * Declare a label for branching to.
474 */
475 case ScriptObjWriterCode.DclLabel: 451 case ScriptObjWriterCode.DclLabel:
476 { 452 {
477 int number = objReader.ReadInt32(); 453 int number = objReader.ReadInt32();
478 string name = objReader.ReadString(); 454 string name = objReader.ReadString();
479 455
480 labels.Add(number, ilGen.DefineLabel()); 456 labels.Add(number, ilGen.DefineLabel());
481 labelNames.Add(number, name + "_" + number.ToString()); 457 labelNames.Add(number, name + "_" + number.ToString());
482 if(objectTokens != null) 458 if(objectTokens != null)
483 objectTokens.DefineLabel(number, name); 459 objectTokens.DefineLabel(number, name);
484 break; 460 break;
485 } 461 }
486 462
487 /* 463 // Declare a local variable to store into.
488 * Declare a local variable to store into.
489 */
490 case ScriptObjWriterCode.DclLocal: 464 case ScriptObjWriterCode.DclLocal:
491 { 465 {
492 int number = objReader.ReadInt32(); 466 int number = objReader.ReadInt32();
493 string name = objReader.ReadString(); 467 string name = objReader.ReadString();
494 string type = objReader.ReadString(); 468 string type = objReader.ReadString();
495 Type syType = GetTypeFromStr(sdTypes, type); 469 Type syType = GetTypeFromStr(sdTypes, type);
496 470
497 locals.Add(number, ilGen.DeclareLocal(syType)); 471 locals.Add(number, ilGen.DeclareLocal(syType));
498 localNames.Add(number, name + "_" + number.ToString()); 472 localNames.Add(number, name + "_" + number.ToString());
499 if(objectTokens != null) 473 if(objectTokens != null)
500 objectTokens.DefineLocal(number, name, type, syType); 474 objectTokens.DefineLocal(number, name, type, syType);
501 break; 475 break;
502 } 476 }
503 477
504 /* 478 // Declare a method that will subsequently be defined.
505 * Declare a method that will subsequently be defined. 479 // We create the DynamicMethod object at this point in case there
506 * We create the DynamicMethod object at this point in case there 480 // are forward references from other method bodies.
507 * are forward references from other method bodies.
508 */
509 case ScriptObjWriterCode.DclMethod: 481 case ScriptObjWriterCode.DclMethod:
482 {
483 string methName = objReader.ReadString();
484 Type retType = GetTypeFromStr(sdTypes, objReader.ReadString());
485 int nArgs = objReader.ReadInt32();
486
487 Type[] argTypes = new Type[nArgs];
488 string[] argNames = new string[nArgs];
489 for(int i = 0; i < nArgs; i++)
510 { 490 {
511 string methName = objReader.ReadString(); 491 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
512 Type retType = GetTypeFromStr(sdTypes, objReader.ReadString()); 492 argNames[i] = objReader.ReadString();
513 int nArgs = objReader.ReadInt32();
514
515 Type[] argTypes = new Type[nArgs];
516 string[] argNames = new string[nArgs];
517 for(int i = 0; i < nArgs; i++)
518 {
519 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
520 argNames[i] = objReader.ReadString();
521 }
522 methods.Add(methName, new DynamicMethod(methName, retType, argTypes));
523 if(objectTokens != null)
524 objectTokens.DefineMethod(methName, retType, argTypes, argNames);
525 break;
526 } 493 }
494 methods.Add(methName, new DynamicMethod(methName, retType, argTypes));
495 if(objectTokens != null)
496 objectTokens.DefineMethod(methName, retType, argTypes, argNames);
497 break;
498 }
527 499
528 /* 500 // Mark a previously declared label at this spot.
529 * Mark a previously declared label at this spot.
530 */
531 case ScriptObjWriterCode.MarkLabel: 501 case ScriptObjWriterCode.MarkLabel:
532 { 502 {
533 int number = objReader.ReadInt32(); 503 int number = objReader.ReadInt32();
534 504
535 ilGen.MarkLabel(labels[number]); 505 ilGen.MarkLabel(labels[number]);
536 506
537 if(objectTokens != null) 507 if(objectTokens != null)
538 objectTokens.MarkLabel(offset, number); 508 objectTokens.MarkLabel(offset, number);
539 break; 509 break;
540 } 510 }
541 511
542 /* 512 // Try/Catch blocks.
543 * Try/Catch blocks.
544 */
545 case ScriptObjWriterCode.BegExcBlk: 513 case ScriptObjWriterCode.BegExcBlk:
546 { 514 {
547 ilGen.BeginExceptionBlock(); 515 ilGen.BeginExceptionBlock();
548 if(objectTokens != null) 516 if(objectTokens != null)
549 objectTokens.BegExcBlk(offset); 517 objectTokens.BegExcBlk(offset);
550 break; 518 break;
551 } 519 }
552 520
553 case ScriptObjWriterCode.BegCatBlk: 521 case ScriptObjWriterCode.BegCatBlk:
554 { 522 {
555 Type excType = GetTypeFromStr(sdTypes, objReader.ReadString()); 523 Type excType = GetTypeFromStr(sdTypes, objReader.ReadString());
556 ilGen.BeginCatchBlock(excType); 524 ilGen.BeginCatchBlock(excType);
557 if(objectTokens != null) 525 if(objectTokens != null)
558 objectTokens.BegCatBlk(offset, excType); 526 objectTokens.BegCatBlk(offset, excType);
559 break; 527 break;
560 } 528 }
561 529
562 case ScriptObjWriterCode.BegFinBlk: 530 case ScriptObjWriterCode.BegFinBlk:
563 { 531 {
564 ilGen.BeginFinallyBlock(); 532 ilGen.BeginFinallyBlock();
565 if(objectTokens != null) 533 if(objectTokens != null)
566 objectTokens.BegFinBlk(offset); 534 objectTokens.BegFinBlk(offset);
567 break; 535 break;
568 } 536 }
569 537
570 case ScriptObjWriterCode.EndExcBlk: 538 case ScriptObjWriterCode.EndExcBlk:
571 { 539 {
572 ilGen.EndExceptionBlock(); 540 ilGen.EndExceptionBlock();
573 if(objectTokens != null) 541 if(objectTokens != null)
574 objectTokens.EndExcBlk(offset); 542 objectTokens.EndExcBlk(offset);
575 break; 543 break;
576 } 544 }
577 545
578 /* 546 // Emit an opcode with no operand.
579 * Emit an opcode with no operand.
580 */
581 case ScriptObjWriterCode.EmitNull: 547 case ScriptObjWriterCode.EmitNull:
582 { 548 {
583 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 549 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
584 550
585 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 551 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
586 ilGen.Emit(opCode); 552 ilGen.Emit(opCode);
587 553
588 if(objectTokens != null) 554 if(objectTokens != null)
589 objectTokens.EmitNull(offset, opCode); 555 objectTokens.EmitNull(offset, opCode);
590 break; 556 break;
591 } 557 }
592 558
593 /* 559 // Emit an opcode with a FieldInfo operand.
594 * Emit an opcode with a FieldInfo operand.
595 */
596 case ScriptObjWriterCode.EmitField: 560 case ScriptObjWriterCode.EmitField:
597 { 561 {
598 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 562 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
599 Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString()); 563 Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString());
600 string fieldName = objReader.ReadString(); 564 string fieldName = objReader.ReadString();
601 565
602 FieldInfo field = reflectedType.GetField(fieldName); 566 FieldInfo field = reflectedType.GetField(fieldName);
603 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 567 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
604 ilGen.Emit(opCode, field); 568 ilGen.Emit(opCode, field);
605 569
606 if(objectTokens != null) 570 if(objectTokens != null)
607 objectTokens.EmitField(offset, opCode, field); 571 objectTokens.EmitField(offset, opCode, field);
608 break; 572 break;
609 } 573 }
610 574
611 /* 575 // Emit an opcode with a LocalBuilder operand.
612 * Emit an opcode with a LocalBuilder operand.
613 */
614 case ScriptObjWriterCode.EmitLocal: 576 case ScriptObjWriterCode.EmitLocal:
615 { 577 {
616 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 578 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
617 int number = objReader.ReadInt32(); 579 int number = objReader.ReadInt32();
618 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 580 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
619 ilGen.Emit(opCode, locals[number]); 581 ilGen.Emit(opCode, locals[number]);
620 582
621 if(objectTokens != null) 583 if(objectTokens != null)
622 objectTokens.EmitLocal(offset, opCode, number); 584 objectTokens.EmitLocal(offset, opCode, number);
623 break; 585 break;
624 } 586 }
625 587
626 /* 588 // Emit an opcode with a Type operand.
627 * Emit an opcode with a Type operand.
628 */
629 case ScriptObjWriterCode.EmitType: 589 case ScriptObjWriterCode.EmitType:
630 { 590 {
631 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 591 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
632 string name = objReader.ReadString(); 592 string name = objReader.ReadString();
633 Type type = GetTypeFromStr(sdTypes, name); 593 Type type = GetTypeFromStr(sdTypes, name);
634 594
635 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 595 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
636 ilGen.Emit(opCode, type); 596 ilGen.Emit(opCode, type);
637 597
638 if(objectTokens != null) 598 if(objectTokens != null)
639 objectTokens.EmitType(offset, opCode, type); 599 objectTokens.EmitType(offset, opCode, type);
640 break; 600 break;
641 } 601 }
642 602
643 /* 603 // Emit an opcode with a Label operand.
644 * Emit an opcode with a Label operand.
645 */
646 case ScriptObjWriterCode.EmitLabel: 604 case ScriptObjWriterCode.EmitLabel:
647 { 605 {
648 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 606 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
649 int number = objReader.ReadInt32(); 607 int number = objReader.ReadInt32();
650 608
651 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 609 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
652 ilGen.Emit(opCode, labels[number]); 610 ilGen.Emit(opCode, labels[number]);
653 611
654 if(objectTokens != null) 612 if(objectTokens != null)
655 objectTokens.EmitLabel(offset, opCode, number); 613 objectTokens.EmitLabel(offset, opCode, number);
656 break; 614 break;
657 } 615 }
658 616
659 /* 617 // Emit an opcode with a Label array operand.
660 * Emit an opcode with a Label array operand.
661 */
662 case ScriptObjWriterCode.EmitLabels: 618 case ScriptObjWriterCode.EmitLabels:
619 {
620 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
621 int nLabels = objReader.ReadInt32();
622 Label[] lbls = new Label[nLabels];
623 int[] nums = new int[nLabels];
624 for(int i = 0; i < nLabels; i++)
663 { 625 {
664 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 626 nums[i] = objReader.ReadInt32();
665 int nLabels = objReader.ReadInt32(); 627 lbls[i] = labels[nums[i]];
666 Label[] lbls = new Label[nLabels]; 628 }
667 int[] nums = new int[nLabels];
668 for(int i = 0; i < nLabels; i++)
669 {
670 nums[i] = objReader.ReadInt32();
671 lbls[i] = labels[nums[i]];
672 }
673 629
674 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 630 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
675 ilGen.Emit(opCode, lbls); 631 ilGen.Emit(opCode, lbls);
676 632
677 if(objectTokens != null) 633 if(objectTokens != null)
678 objectTokens.EmitLabels(offset, opCode, nums); 634 objectTokens.EmitLabels(offset, opCode, nums);
679 break; 635 break;
680 } 636 }
681 637
682 /* 638 // Emit an opcode with a MethodInfo operand (such as a call) of an external function.
683 * Emit an opcode with a MethodInfo operand (such as a call) of an external function.
684 */
685 case ScriptObjWriterCode.EmitMethodExt: 639 case ScriptObjWriterCode.EmitMethodExt:
640 {
641 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
642 string methName = objReader.ReadString();
643 Type methType = GetTypeFromStr(sdTypes, objReader.ReadString());
644 int nArgs = objReader.ReadInt32();
645
646 Type[] argTypes = new Type[nArgs];
647 for(int i = 0; i < nArgs; i++)
686 { 648 {
687 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 649 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
688 string methName = objReader.ReadString();
689 Type methType = GetTypeFromStr(sdTypes, objReader.ReadString());
690 int nArgs = objReader.ReadInt32();
691
692 Type[] argTypes = new Type[nArgs];
693 for(int i = 0; i < nArgs; i++)
694 {
695 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
696 }
697 MethodInfo methInfo = methType.GetMethod(methName, argTypes);
698 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
699 ilGen.Emit(opCode, methInfo);
700
701 if(objectTokens != null)
702 objectTokens.EmitMethod(offset, opCode, methInfo);
703 break;
704 } 650 }
651 MethodInfo methInfo = methType.GetMethod(methName, argTypes);
652 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
653 ilGen.Emit(opCode, methInfo);
654
655 if(objectTokens != null)
656 objectTokens.EmitMethod(offset, opCode, methInfo);
657 break;
658 }
705 659
706 /* 660 // Emit an opcode with a MethodInfo operand of an internal function
707 * Emit an opcode with a MethodInfo operand of an internal function 661 // (previously declared via DclMethod).
708 * (previously declared via DclMethod).
709 */
710 case ScriptObjWriterCode.EmitMethodInt: 662 case ScriptObjWriterCode.EmitMethodInt:
711 { 663 {
712 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 664 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
713 string methName = objReader.ReadString(); 665 string methName = objReader.ReadString();
714 666
715 MethodInfo methInfo = methods[methName]; 667 MethodInfo methInfo = methods[methName];
716 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 668 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
717 ilGen.Emit(opCode, methInfo); 669 ilGen.Emit(opCode, methInfo);
718 670
719 if(objectTokens != null) 671 if(objectTokens != null)
720 objectTokens.EmitMethod(offset, opCode, methInfo); 672 objectTokens.EmitMethod(offset, opCode, methInfo);
721 break; 673 break;
722 } 674 }
723 675
724 /* 676 // Emit an opcode with a ConstructorInfo operand.
725 * Emit an opcode with a ConstructorInfo operand.
726 */
727 case ScriptObjWriterCode.EmitCtor: 677 case ScriptObjWriterCode.EmitCtor:
678 {
679 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
680 Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString());
681 int nArgs = objReader.ReadInt32();
682 Type[] argTypes = new Type[nArgs];
683 for(int i = 0; i < nArgs; i++)
728 { 684 {
729 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 685 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
730 Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString()); 686 }
731 int nArgs = objReader.ReadInt32();
732 Type[] argTypes = new Type[nArgs];
733 for(int i = 0; i < nArgs; i++)
734 {
735 argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString());
736 }
737 687
738 ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes); 688 ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes);
739 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 689 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
740 ilGen.Emit(opCode, ctorInfo); 690 ilGen.Emit(opCode, ctorInfo);
741 691
742 if(objectTokens != null) 692 if(objectTokens != null)
743 objectTokens.EmitCtor(offset, opCode, ctorInfo); 693 objectTokens.EmitCtor(offset, opCode, ctorInfo);
744 break; 694 break;
745 } 695 }
746 696
747 /* 697 // Emit an opcode with a constant operand of various types.
748 * Emit an opcode with a constant operand of various types.
749 */
750 case ScriptObjWriterCode.EmitDouble: 698 case ScriptObjWriterCode.EmitDouble:
751 { 699 {
752 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 700 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
753 double value = objReader.ReadDouble(); 701 double value = objReader.ReadDouble();
754 702
755 if(opCode != OpCodes.Ldc_R8) 703 if(opCode != OpCodes.Ldc_R8)
756 { 704 {
757 throw new Exception("bad opcode " + opCode.ToString()); 705 throw new Exception("bad opcode " + opCode.ToString());
758 }
759 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
760 ilGen.Emit(opCode, value);
761
762 if(objectTokens != null)
763 objectTokens.EmitDouble(offset, opCode, value);
764 break;
765 } 706 }
707 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
708 ilGen.Emit(opCode, value);
766 709
767 case ScriptObjWriterCode.EmitFloat: 710 if(objectTokens != null)
768 { 711 objectTokens.EmitDouble(offset, opCode, value);
769 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 712 break;
770 float value = objReader.ReadSingle(); 713 }
771 714
772 if(opCode != OpCodes.Ldc_R4) 715 case ScriptObjWriterCode.EmitFloat:
773 { 716 {
774 throw new Exception("bad opcode " + opCode.ToString()); 717 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
775 } 718 float value = objReader.ReadSingle();
776 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
777 ilGen.Emit(opCode, value);
778 719
779 if(objectTokens != null) 720 if(opCode != OpCodes.Ldc_R4)
780 objectTokens.EmitFloat(offset, opCode, value); 721 {
781 break; 722 throw new Exception("bad opcode " + opCode.ToString());
782 } 723 }
724 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
725 ilGen.Emit(opCode, value);
726
727 if(objectTokens != null)
728 objectTokens.EmitFloat(offset, opCode, value);
729 break;
730 }
783 731
784 case ScriptObjWriterCode.EmitInteger: 732 case ScriptObjWriterCode.EmitInteger:
785 { 733 {
786 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 734 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
787 int value = objReader.ReadInt32(); 735 int value = objReader.ReadInt32();
788 736
789 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 737 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
790 738
791 if(opCode == OpCodes.Ldc_I4) 739 if(opCode == OpCodes.Ldc_I4)
740 {
741 if((value >= -1) && (value <= 8))
792 { 742 {
793 if((value >= -1) && (value <= 8)) 743 opCode = opCodesLdcI4M1P8[value + 1];
794 { 744 ilGen.Emit(opCode);
795 opCode = opCodesLdcI4M1P8[value + 1]; 745 if(objectTokens != null)
796 ilGen.Emit(opCode); 746 objectTokens.EmitNull(offset, opCode);
797 if(objectTokens != null) 747 break;
798 objectTokens.EmitNull(offset, opCode); 748 }
799 break; 749 if((value >= 0) && (value <= 127))
800 } 750 {
801 if((value >= 0) && (value <= 127)) 751 opCode = OpCodes.Ldc_I4_S;
802 { 752 ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
803 opCode = OpCodes.Ldc_I4_S; 753 goto pemitint;
804 ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
805 goto pemitint;
806 }
807 } 754 }
808
809 ilGen.Emit(opCode, value);
810 pemitint:
811 if(objectTokens != null)
812 objectTokens.EmitInteger(offset, opCode, value);
813 break;
814 } 755 }
815 756
757 ilGen.Emit(opCode, value);
758 pemitint:
759 if(objectTokens != null)
760 objectTokens.EmitInteger(offset, opCode, value);
761 break;
762 }
763
816 case ScriptObjWriterCode.EmitString: 764 case ScriptObjWriterCode.EmitString:
817 { 765 {
818 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); 766 OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn);
819 string value = objReader.ReadString(); 767 string value = objReader.ReadString();
820 768
821 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); 769 SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn);
822 ilGen.Emit(opCode, value); 770 ilGen.Emit(opCode, value);
823 771
824 if(objectTokens != null) 772 if(objectTokens != null)
825 objectTokens.EmitString(offset, opCode, value); 773 objectTokens.EmitString(offset, opCode, value);
826 break; 774 break;
827 } 775 }
828 776
829 /* 777 // Who knows what?
830 * Who knows what?
831 */
832 default: 778 default:
833 throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString()); 779 throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString());
834 } 780 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs
index b0653f7..85bc9aa 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs
@@ -58,7 +58,6 @@ using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
58 58
59namespace OpenSim.Region.ScriptEngine.Yengine 59namespace OpenSim.Region.ScriptEngine.Yengine
60{ 60{
61
62 public class ScriptReduce 61 public class ScriptReduce
63 { 62 {
64 public const uint SDT_PRIVATE = 1; 63 public const uint SDT_PRIVATE = 1;
@@ -177,25 +176,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
177 */ 176 */
178 private ScriptReduce(TokenBegin tokenBegin) 177 private ScriptReduce(TokenBegin tokenBegin)
179 { 178 {
180 /* 179 // Create a place to put the top-level script components,
181 * Create a place to put the top-level script components, 180 // eg, state bodies, functions, global variables.
182 * eg, state bodies, functions, global variables.
183 */
184 tokenScript = new TokenScript(tokenBegin.nextToken); 181 tokenScript = new TokenScript(tokenBegin.nextToken);
185 182
186 /* 183 // 'class', 'delegate', 'instance' all define types.
187 * 'class', 'delegate', 'instance' all define types. 184 // So we pre-scan the source tokens for those keywords
188 * So we pre-scan the source tokens for those keywords 185 // to build a script-defined type table and substitute
189 * to build a script-defined type table and substitute 186 // type tokens for those names in the source. This is
190 * type tokens for those names in the source. This is 187 // done as a separate scan so they can cross-reference
191 * done as a separate scan so they can cross-reference 188 // each other. Also does likewise for fixed array types.
192 * each other. Also does likewise for fixed array types. 189 //
193 * 190 // Also, all 'typedef's are processed here. Their definitions
194 * Also, all 'typedef's are processed here. Their definitions 191 // remain in the source token stream after this, but they can
195 * remain in the source token stream after this, but they can 192 // be skipped over, because their bodies have been substituted
196 * be skipped over, because their bodies have been substituted 193 // in the source for any references.
197 * in the source for any references.
198 */
199 ParseSDTypePreScanPassOne(tokenBegin); // catalog definitions 194 ParseSDTypePreScanPassOne(tokenBegin); // catalog definitions
200 ParseSDTypePreScanPassTwo(tokenBegin); // substitute references 195 ParseSDTypePreScanPassTwo(tokenBegin); // substitute references
201 196
@@ -226,10 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
226 } 221 }
227 */ 222 */
228 223
229 /* 224 // Create a function $globalvarinit to hold all explicit
230 * Create a function $globalvarinit to hold all explicit 225 // global variable initializations.
231 * global variable initializations.
232 */
233 TokenDeclVar gviFunc = new TokenDeclVar(tokenBegin, null, tokenScript); 226 TokenDeclVar gviFunc = new TokenDeclVar(tokenBegin, null, tokenScript);
234 gviFunc.name = new TokenName(gviFunc, "$globalvarinit"); 227 gviFunc.name = new TokenName(gviFunc, "$globalvarinit");
235 gviFunc.retType = new TokenTypeVoid(gviFunc); 228 gviFunc.retType = new TokenTypeVoid(gviFunc);
@@ -240,9 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
240 tokenScript.globalVarInit = gviFunc; 233 tokenScript.globalVarInit = gviFunc;
241 tokenScript.AddVarEntry(gviFunc); 234 tokenScript.AddVarEntry(gviFunc);
242 235
243 /* 236 // Scan through the tokens until we reach the end.
244 * Scan through the tokens until we reach the end.
245 */
246 for(Token token = tokenBegin.nextToken; !(token is TokenEnd);) 237 for(Token token = tokenBegin.nextToken; !(token is TokenEnd);)
247 { 238 {
248 if(token is TokenKwSemi) 239 if(token is TokenKwSemi)
@@ -251,25 +242,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
251 continue; 242 continue;
252 } 243 }
253 244
254 /* 245 // Script-defined type declarations.
255 * Script-defined type declarations.
256 */
257 if(ParseDeclSDTypes(ref token, null, SDT_PUBLIC)) 246 if(ParseDeclSDTypes(ref token, null, SDT_PUBLIC))
258 continue; 247 continue;
259 248
260 /* 249 // constant <name> = <rval> ;
261 * constant <name> = <rval> ;
262 */
263 if(token is TokenKwConst) 250 if(token is TokenKwConst)
264 { 251 {
265 ParseDeclVar(ref token, null); 252 ParseDeclVar(ref token, null);
266 continue; 253 continue;
267 } 254 }
268 255
269 /* 256 // <type> <name> ;
270 * <type> <name> ; 257 // <type> <name> = <rval> ;
271 * <type> <name> = <rval> ;
272 */
273 if((token is TokenType) && 258 if((token is TokenType) &&
274 (token.nextToken is TokenName) && 259 (token.nextToken is TokenName) &&
275 ((token.nextToken.nextToken is TokenKwSemi) || 260 ((token.nextToken.nextToken is TokenKwSemi) ||
@@ -285,9 +270,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
285 continue; 270 continue;
286 } 271 }
287 272
288 /* 273 // <type> <name> { [ get { <body> } ] [ set { <body> } ] }
289 * <type> <name> { [ get { <body> } ] [ set { <body> } ] }
290 */
291 if((token is TokenType) && 274 if((token is TokenType) &&
292 (token.nextToken is TokenName) && 275 (token.nextToken is TokenName) &&
293 (token.nextToken.nextToken is TokenKwBrcOpen)) 276 (token.nextToken.nextToken is TokenKwBrcOpen))
@@ -296,10 +279,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
296 continue; 279 continue;
297 } 280 }
298 281
299 /* 282 // <type> <name> <funcargs> <funcbody>
300 * <type> <name> <funcargs> <funcbody> 283 // global function returning specified type
301 * global function returning specified type
302 */
303 if(token is TokenType) 284 if(token is TokenType)
304 { 285 {
305 TokenType tokenType = (TokenType)token; 286 TokenType tokenType = (TokenType)token;
@@ -330,10 +311,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
330 continue; 311 continue;
331 } 312 }
332 313
333 /* 314 // <name> <funcargs> <funcbody>
334 * <name> <funcargs> <funcbody> 315 // global function returning void
335 * global function returning void
336 */
337 if(token is TokenName) 316 if(token is TokenName)
338 { 317 {
339 TokenName tokenName = (TokenName)token; 318 TokenName tokenName = (TokenName)token;
@@ -355,9 +334,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
355 continue; 334 continue;
356 } 335 }
357 336
358 /* 337 // default <statebody>
359 * default <statebody>
360 */
361 if(token is TokenKwDefault) 338 if(token is TokenKwDefault)
362 { 339 {
363 TokenDeclState tokenDeclState = new TokenDeclState(token); 340 TokenDeclState tokenDeclState = new TokenDeclState(token);
@@ -374,9 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
374 continue; 351 continue;
375 } 352 }
376 353
377 /* 354 // state <name> <statebody>
378 * state <name> <statebody>
379 */
380 if(token is TokenKwState) 355 if(token is TokenKwState)
381 { 356 {
382 TokenDeclState tokenDeclState = new TokenDeclState(token); 357 TokenDeclState tokenDeclState = new TokenDeclState(token);
@@ -401,25 +376,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
401 continue; 376 continue;
402 } 377 }
403 378
404 /* 379 // Doesn't fit any of those forms, output message and skip to next statement.
405 * Doesn't fit any of those forms, output message and skip to next statement.
406 */
407 ErrorMsg(token, "looking for var name, type, state or default, script-defined type declaration"); 380 ErrorMsg(token, "looking for var name, type, state or default, script-defined type declaration");
408 token = SkipPastSemi(token); 381 token = SkipPastSemi(token);
409 continue; 382 continue;
410 } 383 }
411 384
412 /* 385 // Must have a default state to start in.
413 * Must have a default state to start in.
414 */
415 if(!errors && (tokenScript.defaultState == null)) 386 if(!errors && (tokenScript.defaultState == null))
416 { 387 {
417 ErrorMsg(tokenScript, "no default state defined"); 388 ErrorMsg(tokenScript, "no default state defined");
418 } 389 }
419 390
420 /* 391 // If any error messages were written out, set return value to null.
421 * If any error messages were written out, set return value to null.
422 */
423 if(errors) 392 if(errors)
424 tokenScript = null; 393 tokenScript = null;
425 } 394 }
@@ -444,10 +413,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
444 413
445 for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) 414 for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);)
446 { 415 {
447 /* 416 // Keep track of nested definitions so we can link them up.
448 * Keep track of nested definitions so we can link them up. 417 // We also need to detect the end of class and interface definitions.
449 * We also need to detect the end of class and interface definitions.
450 */
451 if(t is TokenKwBrcOpen) 418 if(t is TokenKwBrcOpen)
452 { 419 {
453 openBraceLevel++; 420 openBraceLevel++;
@@ -468,11 +435,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
468 continue; 435 continue;
469 } 436 }
470 437
471 /* 438 // Check for 'class' or 'interface'.
472 * Check for 'class' or 'interface'. 439 // They always define a new class or interface.
473 * They always define a new class or interface. 440 // They can contain nested script-defined type definitions.
474 * They can contain nested script-defined type definitions.
475 */
476 if((t is TokenKwClass) || (t is TokenKwInterface)) 441 if((t is TokenKwClass) || (t is TokenKwInterface))
477 { 442 {
478 Token kw = t; 443 Token kw = t;
@@ -486,9 +451,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
486 TokenName name = (TokenName)t; 451 TokenName name = (TokenName)t;
487 t = t.nextToken; 452 t = t.nextToken;
488 453
489 /* 454 // Malloc the script-defined type object.
490 * Malloc the script-defined type object.
491 */
492 TokenDeclSDType decl; 455 TokenDeclSDType decl;
493 if(kw is TokenKwClass) 456 if(kw is TokenKwClass)
494 decl = new TokenDeclSDTypeClass(name, kw.prevToken is TokenKwPartial); 457 decl = new TokenDeclSDTypeClass(name, kw.prevToken is TokenKwPartial);
@@ -496,56 +459,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine
496 decl = new TokenDeclSDTypeInterface(name); 459 decl = new TokenDeclSDTypeInterface(name);
497 decl.outerSDType = outerLevels.Peek(); 460 decl.outerSDType = outerLevels.Peek();
498 461
499 /* 462 // Check for generic parameter list.
500 * Check for generic parameter list.
501 */
502 if(!ParseGenProtoParamList(ref t, decl)) 463 if(!ParseGenProtoParamList(ref t, decl))
503 continue; 464 continue;
504 465
505 /* 466 // Splice in a TokenDeclSDType token that replaces the keyword and the name tokens
506 * Splice in a TokenDeclSDType token that replaces the keyword and the name tokens 467 // and any generic parameters including the '<', ','s and '>'.
507 * and any generic parameters including the '<', ','s and '>'. 468 // kw = points to 'class' or 'interface' keyword.
508 * kw = points to 'class' or 'interface' keyword. 469 // t = points to just past last part of class name parsed, hopefully a ':' or '{'.
509 * t = points to just past last part of class name parsed, hopefully a ':' or '{'.
510 */
511 decl.prevToken = decl.isPartial ? kw.prevToken.prevToken : kw.prevToken; 470 decl.prevToken = decl.isPartial ? kw.prevToken.prevToken : kw.prevToken;
512 decl.nextToken = t; 471 decl.nextToken = t;
513 decl.prevToken.nextToken = decl; 472 decl.prevToken.nextToken = decl;
514 decl.nextToken.prevToken = decl; 473 decl.nextToken.prevToken = decl;
515 474
516 /* 475 // Enter it in name lists so it can be seen by others.
517 * Enter it in name lists so it can be seen by others.
518 */
519 Token partialNewBody = CatalogSDTypeDecl(decl); 476 Token partialNewBody = CatalogSDTypeDecl(decl);
520 477
521 /* 478 // Start inner type definitions.
522 * Start inner type definitions.
523 */
524 braceLevels.Push(openBraceLevel); 479 braceLevels.Push(openBraceLevel);
525 outerLevels.Push(decl); 480 outerLevels.Push(decl);
526 481
527 /* 482 // Scan the body starting on for before the '{'.
528 * Scan the body starting on for before the '{'. 483 //
529 * 484 // If this body had an old partial merged into it,
530 * If this body had an old partial merged into it, 485 // resume scanning at the beginning of the new body,
531 * resume scanning at the beginning of the new body, 486 // ie, what used to be the first token after the '{'
532 * ie, what used to be the first token after the '{' 487 // before the old body was spliced in.
533 * before the old body was spliced in.
534 */
535 if(partialNewBody != null) 488 if(partialNewBody != null)
536 { 489 {
537 490 // We have a partial that has had old partial body merged
538 /* 491 // into new partial body. So resume scanning at the beginning
539 * We have a partial that has had old partial body merged 492 // of the new partial body so we don't get any duplicate scanning
540 * into new partial body. So resume scanning at the beginning 493 // of the old partial body.
541 * of the new partial body so we don't get any duplicate scanning 494 //
542 * of the old partial body. 495 // <decl> ... { <oldbody> <newbody> }
543 * 496 // ^- resume scanning here
544 * <decl> ... { <oldbody> <newbody> } 497 // but inc openBraceLevel because
545 * ^- resume scanning here 498 // we skipped scanning the '{'
546 * but inc openBraceLevel because
547 * we skipped scanning the '{'
548 */
549 openBraceLevel++; 499 openBraceLevel++;
550 t = partialNewBody; 500 t = partialNewBody;
551 } 501 }
@@ -553,23 +503,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
553 continue; 503 continue;
554 } 504 }
555 505
556 /* 506 // Check for 'delegate'.
557 * Check for 'delegate'. 507 // It always defines a new delegate.
558 * It always defines a new delegate. 508 // Delegates never define nested types.
559 * Delegates never define nested types.
560 */
561 if(t is TokenKwDelegate) 509 if(t is TokenKwDelegate)
562 { 510 {
563 Token kw = t; 511 Token kw = t;
564 t = t.nextToken; 512 t = t.nextToken;
565 513
566 /* 514 // Next thing might be an explicit return type or the delegate's name.
567 * Next thing might be an explicit return type or the delegate's name. 515 // If it's a type token, then it's the return type, simple enough.
568 * If it's a type token, then it's the return type, simple enough. 516 // But if it's a name token, it might be the name of some other script-defined type.
569 * But if it's a name token, it might be the name of some other script-defined type. 517 // The way to tell is that the delegate name is followed by a '(', whereas an
570 * The way to tell is that the delegate name is followed by a '(', whereas an 518 // explicit return type is followed by the delegate name.
571 * explicit return type is followed by the delegate name.
572 */
573 Token retType = t; 519 Token retType = t;
574 TokenName delName = null; 520 TokenName delName = null;
575 Token u; 521 Token u;
@@ -602,29 +548,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
602 if(retType == delName) 548 if(retType == delName)
603 retType = null; 549 retType = null;
604 550
605 /* 551 // Malloc the script-defined type object.
606 * Malloc the script-defined type object.
607 */
608 TokenDeclSDTypeDelegate decl = new TokenDeclSDTypeDelegate(delName); 552 TokenDeclSDTypeDelegate decl = new TokenDeclSDTypeDelegate(delName);
609 decl.outerSDType = outerLevels.Peek(); 553 decl.outerSDType = outerLevels.Peek();
610 554
611 /* 555 // Check for generic parameter list.
612 * Check for generic parameter list.
613 */
614 t = delName.nextToken; 556 t = delName.nextToken;
615 if(!ParseGenProtoParamList(ref t, decl)) 557 if(!ParseGenProtoParamList(ref t, decl))
616 continue; 558 continue;
617 559
618 /* 560 // Enter it in name lists so it can be seen by others.
619 * Enter it in name lists so it can be seen by others.
620 */
621 CatalogSDTypeDecl(decl); 561 CatalogSDTypeDecl(decl);
622 562
623 /* 563 // Splice in the token that replaces the 'delegate' keyword and the whole name
624 * Splice in the token that replaces the 'delegate' keyword and the whole name 564 // (including the '<' name ... '>' parts). The return type token(s), if any,
625 * (including the '<' name ... '>' parts). The return type token(s), if any, 565 // follow the splice token and come before the '('.
626 * follow the splice token and come before the '('.
627 */
628 decl.prevToken = kw.prevToken; 566 decl.prevToken = kw.prevToken;
629 kw.prevToken.nextToken = decl; 567 kw.prevToken.nextToken = decl;
630 568
@@ -641,10 +579,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
641 t.prevToken = retType; 579 t.prevToken = retType;
642 } 580 }
643 581
644 /* 582 // Scan for terminating ';'.
645 * Scan for terminating ';'. 583 // There cannot be an intervening class, delegate, interfate, typedef, { or }.
646 * There cannot be an intervening class, delegate, interfate, typedef, { or }.
647 */
648 for(t = decl; !(t is TokenKwSemi); t = u) 584 for(t = decl; !(t is TokenKwSemi); t = u)
649 { 585 {
650 u = t.nextToken; 586 u = t.nextToken;
@@ -664,11 +600,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
664 continue; 600 continue;
665 } 601 }
666 602
667 /* 603 // Check for 'typedef'.
668 * Check for 'typedef'. 604 // It always defines a new macro.
669 * It always defines a new macro. 605 // Typedefs never define nested types.
670 * Typedefs never define nested types.
671 */
672 if(t is TokenKwTypedef) 606 if(t is TokenKwTypedef)
673 { 607 {
674 Token kw = t; 608 Token kw = t;
@@ -683,37 +617,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
683 TokenName tdName = (TokenName)t; 617 TokenName tdName = (TokenName)t;
684 t = t.nextToken; 618 t = t.nextToken;
685 619
686 /* 620 // Malloc the script-defined type object.
687 * Malloc the script-defined type object.
688 */
689 TokenDeclSDTypeTypedef decl = new TokenDeclSDTypeTypedef(tdName); 621 TokenDeclSDTypeTypedef decl = new TokenDeclSDTypeTypedef(tdName);
690 decl.outerSDType = outerLevels.Peek(); 622 decl.outerSDType = outerLevels.Peek();
691 623
692 /* 624 // Check for generic parameter list.
693 * Check for generic parameter list.
694 */
695 if(!ParseGenProtoParamList(ref t, decl)) 625 if(!ParseGenProtoParamList(ref t, decl))
696 continue; 626 continue;
697 627
698 /* 628 // Enter it in name lists so it can be seen by others.
699 * Enter it in name lists so it can be seen by others.
700 */
701 CatalogSDTypeDecl(decl); 629 CatalogSDTypeDecl(decl);
702 numTypedefs++; 630 numTypedefs++;
703 631
704 /* 632 // Splice in the token that replaces the 'typedef' keyword and the whole name
705 * Splice in the token that replaces the 'typedef' keyword and the whole name 633 // (including the '<' name ... '>' parts).
706 * (including the '<' name ... '>' parts).
707 */
708 decl.prevToken = kw.prevToken; 634 decl.prevToken = kw.prevToken;
709 kw.prevToken.nextToken = decl; 635 kw.prevToken.nextToken = decl;
710 decl.nextToken = t; 636 decl.nextToken = t;
711 t.prevToken = decl; 637 t.prevToken = decl;
712 638
713 /* 639 // Scan for terminating ';'.
714 * Scan for terminating ';'. 640 // There cannot be an intervening class, delegate, interfate, typedef, { or }.
715 * There cannot be an intervening class, delegate, interfate, typedef, { or }.
716 */
717 Token u; 641 Token u;
718 for(t = decl; !(t is TokenKwSemi); t = u) 642 for(t = decl; !(t is TokenKwSemi); t = u)
719 { 643 {
@@ -747,16 +671,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
747 */ 671 */
748 private bool ParseGenProtoParamList(ref Token t, TokenDeclSDType decl) 672 private bool ParseGenProtoParamList(ref Token t, TokenDeclSDType decl)
749 { 673 {
750 /* 674 // Maybe there aren't any generic parameters.
751 * Maybe there aren't any generic parameters. 675 // If so, leave decl.genParams = null.
752 * If so, leave decl.genParams = null.
753 */
754 if(!(t is TokenKwCmpLT)) 676 if(!(t is TokenKwCmpLT))
755 return true; 677 return true;
756 678
757 /* 679 // Build list of generic parameter names.
758 * Build list of generic parameter names.
759 */
760 Dictionary<string, int> parms = new Dictionary<string, int>(); 680 Dictionary<string, int> parms = new Dictionary<string, int>();
761 do 681 do
762 { 682 {
@@ -813,17 +733,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
813 if(!GenericParametersMatch(decl, dupDecl)) 733 if(!GenericParametersMatch(decl, dupDecl))
814 ErrorMsg(decl, "all partial class generic parameters must match"); 734 ErrorMsg(decl, "all partial class generic parameters must match");
815 735
816 /* 736 // Have new declaration be the cataloged one because body is going to get
817 * Have new declaration be the cataloged one because body is going to get 737 // snipped out of old declaration and pasted into new declaration.
818 * snipped out of old declaration and pasted into new declaration.
819 */
820 tokenScript.sdSrcTypesRep(longName, decl); 738 tokenScript.sdSrcTypesRep(longName, decl);
821 if(decl.outerSDType != null) 739 if(decl.outerSDType != null)
822 decl.outerSDType.innerSDTypes[decl.shortName.val] = decl; 740 decl.outerSDType.innerSDTypes[decl.shortName.val] = decl;
823 741
824 /* 742 // Find old partial definition's opening brace.
825 * Find old partial definition's opening brace.
826 */
827 Token dupBrcOpen; 743 Token dupBrcOpen;
828 for(dupBrcOpen = dupDecl; !(dupBrcOpen is TokenKwBrcOpen); dupBrcOpen = dupBrcOpen.nextToken) 744 for(dupBrcOpen = dupDecl; !(dupBrcOpen is TokenKwBrcOpen); dupBrcOpen = dupBrcOpen.nextToken)
829 { 745 {
@@ -834,9 +750,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
834 } 750 }
835 } 751 }
836 752
837 /* 753 // Find new partial definition's opening brace.
838 * Find new partial definition's opening brace.
839 */
840 Token brcOpen; 754 Token brcOpen;
841 for(brcOpen = decl; !(brcOpen is TokenKwBrcOpen); brcOpen = brcOpen.nextToken) 755 for(brcOpen = decl; !(brcOpen is TokenKwBrcOpen); brcOpen = brcOpen.nextToken)
842 { 756 {
@@ -848,25 +762,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
848 } 762 }
849 Token body = brcOpen.nextToken; 763 Token body = brcOpen.nextToken;
850 764
851 /* 765 // Stick old partial definition's extends/implementeds list just
852 * Stick old partial definition's extends/implementeds list just 766 // in front of new partial definition's extends/implementeds list.
853 * in front of new partial definition's extends/implementeds list. 767 //
854 * 768 // class oldextimp { oldbody } ...
855 * class oldextimp { oldbody } ... 769 // dupDecl dupBrcOpen dupDecl.endToken
856 * dupDecl dupBrcOpen dupDecl.endToken 770 //
857 * 771 // class newextimp { newbody } ...
858 * class newextimp { newbody } ... 772 // decl brcOpen body decl.endToken
859 * decl brcOpen body decl.endToken 773 //
860 * 774 // becomes
861 * becomes 775 //
862 * 776 // class ...
863 * class ... 777 // dupDecl
864 * dupDecl 778 // dupDecl.endToken
865 * dupDecl.endToken 779 //
866 * 780 // class oldextimp newextimp { oldbody newbody } ...
867 * class oldextimp newextimp { oldbody newbody } ... 781 // decl brcOpen body decl.endToken
868 * decl brcOpen body decl.endToken
869 */
870 if(dupBrcOpen != dupDecl.nextToken) 782 if(dupBrcOpen != dupDecl.nextToken)
871 { 783 {
872 dupBrcOpen.prevToken.nextToken = decl.nextToken; 784 dupBrcOpen.prevToken.nextToken = decl.nextToken;
@@ -875,10 +787,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
875 decl.nextToken = dupDecl.nextToken; 787 decl.nextToken = dupDecl.nextToken;
876 } 788 }
877 789
878 /* 790 // Stick old partial definition's body just
879 * Stick old partial definition's body just 791 // in front of new partial definition's body.
880 * in front of new partial definition's body.
881 */
882 if(dupBrcOpen.nextToken != dupDecl.endToken) 792 if(dupBrcOpen.nextToken != dupDecl.endToken)
883 { 793 {
884 dupBrcOpen.nextToken.prevToken = brcOpen; 794 dupBrcOpen.nextToken.prevToken = brcOpen;
@@ -887,10 +797,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
887 brcOpen.nextToken = dupBrcOpen.nextToken; 797 brcOpen.nextToken = dupBrcOpen.nextToken;
888 } 798 }
889 799
890 /* 800 // Null out old definition's extends/implementeds list and body
891 * Null out old definition's extends/implementeds list and body 801 // by having the declaration token be the only thing left.
892 * by having the declaration token be the only thing left.
893 */
894 dupDecl.nextToken = dupDecl.endToken.nextToken; 802 dupDecl.nextToken = dupDecl.endToken.nextToken;
895 dupDecl.nextToken.prevToken = dupDecl; 803 dupDecl.nextToken.prevToken = dupDecl;
896 dupDecl.endToken = dupDecl; 804 dupDecl.endToken = dupDecl;
@@ -946,41 +854,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
946 854
947 for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) 855 for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);)
948 { 856 {
949 857 // Maybe it's time to pop out of an outer class definition.
950 /*
951 * Maybe it's time to pop out of an outer class definition.
952 */
953 if((outerSDType != null) && (outerSDType.endToken == t)) 858 if((outerSDType != null) && (outerSDType.endToken == t))
954 { 859 {
955 outerSDType = outerSDType.outerSDType; 860 outerSDType = outerSDType.outerSDType;
956 continue; 861 continue;
957 } 862 }
958 863
959 /* 864 // Skip completely over any script-defined generic prototypes.
960 * Skip completely over any script-defined generic prototypes. 865 // We only need to process their instantiations which are non-
961 * We only need to process their instantiations which are non- 866 // generic versions of the generics.
962 * generic versions of the generics.
963 */
964 if((t is TokenDeclSDType) && (((TokenDeclSDType)t).genParams != null)) 867 if((t is TokenDeclSDType) && (((TokenDeclSDType)t).genParams != null))
965 { 868 {
966 t = ((TokenDeclSDType)t).endToken; 869 t = ((TokenDeclSDType)t).endToken;
967 continue; 870 continue;
968 } 871 }
969 872
970 /* 873 // Check for beginning of non-generic script-defined type definitions.
971 * Check for beginning of non-generic script-defined type definitions. 874 // They can have nested definitions in their innerSDTypes[] that match
972 * They can have nested definitions in their innerSDTypes[] that match 875 // name tokens, so add them to the stack.
973 * name tokens, so add them to the stack. 876 //
974 * 877 // But just ignore any preliminary partial definitions as they have had
975 * But just ignore any preliminary partial definitions as they have had 878 // their entire contents spliced out and spliced into a subsequent partial
976 * their entire contents spliced out and spliced into a subsequent partial 879 // definition. So if we originally had:
977 * definition. So if we originally had: 880 // partial class Abc { public intenger one; }
978 * partial class Abc { public intenger one; } 881 // partial class Abc { public intenger two; }
979 * partial class Abc { public intenger two; } 882 // We now have:
980 * We now have: 883 // partial_class_Abc <== if we are here, just ignore the partial_class_Abc token
981 * partial_class_Abc <== if we are here, just ignore the partial_class_Abc token 884 // partial_class_Abc { public intenger one; public intenger two; }
982 * partial_class_Abc { public intenger one; public intenger two; }
983 */
984 if(t is TokenDeclSDType) 885 if(t is TokenDeclSDType)
985 { 886 {
986 if(((TokenDeclSDType)t).endToken != t) 887 if(((TokenDeclSDType)t).endToken != t)
@@ -989,22 +890,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
989 continue; 890 continue;
990 } 891 }
991 892
992 /* 893 // For names not preceded by a '.', scan the script-defined type definition
993 * For names not preceded by a '.', scan the script-defined type definition 894 // stack for that name. Splice the name out and replace with equivalent token.
994 * stack for that name. Splice the name out and replace with equivalent token.
995 */
996 if((t is TokenName) && !(t.prevToken is TokenKwDot)) 895 if((t is TokenName) && !(t.prevToken is TokenKwDot))
997 t = TrySpliceTypeRef(t, outerSDType, ref repeat, noTypes); 896 t = TrySpliceTypeRef(t, outerSDType, ref repeat, noTypes);
998 897
999 /* 898 // This handles types such as integer[,][], List<string>[], etc.
1000 * This handles types such as integer[,][], List<string>[], etc. 899 // They are an instantiation of an internally generated type of the same name, brackets and all.
1001 * They are an instantiation of an internally generated type of the same name, brackets and all. 900 // Note that to malloc an array, use something like 'new float[,][](3,5)', not 'new float[3,5][]'.
1002 * Note that to malloc an array, use something like 'new float[,][](3,5)', not 'new float[3,5][]'. 901 //
1003 * 902 // Note that we must not get confused by $idxprop property declarations such as:
1004 * Note that we must not get confused by $idxprop property declarations such as: 903 // float [string kee] { get { ... } }
1005 * float [string kee] { get { ... } } 904 // ... and try to convert 'float' '[' to an array type.
1006 * ... and try to convert 'float' '[' to an array type.
1007 */
1008 if((t is TokenType) && (t.nextToken is TokenKwBrkOpen)) 905 if((t is TokenType) && (t.nextToken is TokenKwBrkOpen))
1009 { 906 {
1010 if((t.nextToken.nextToken is TokenKwBrkClose) || 907 if((t.nextToken.nextToken is TokenKwBrkClose) ||
@@ -1015,19 +912,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1015 } 912 }
1016 } 913 }
1017 914
1018 /* 915 // If we instantiated a generic, loop back to process its contents
1019 * If we instantiated a generic, loop back to process its contents 916 // just as if the source code had the instantiated code to begin with.
1020 * just as if the source code had the instantiated code to begin with. 917 // Also repeat if we found a non-type inside the <> of a generic reference
1021 * Also repeat if we found a non-type inside the <> of a generic reference 918 // provided we have made at least one name->type substitution.
1022 * provided we have made at least one name->type substitution.
1023 */
1024 } while(((repeat & REPEAT_INSTGEN) != 0) || 919 } while(((repeat & REPEAT_INSTGEN) != 0) ||
1025 ((repeat & (REPEAT_NOTYPE | REPEAT_SUBST)) == (REPEAT_NOTYPE | REPEAT_SUBST))); 920 ((repeat & (REPEAT_NOTYPE | REPEAT_SUBST)) == (REPEAT_NOTYPE | REPEAT_SUBST)));
1026 921
1027 /* 922 // These are places where we required a type be present,
1028 * These are places where we required a type be present, 923 // eg, a generic type argument or the body of a typedef.
1029 * eg, a generic type argument or the body of a typedef.
1030 */
1031 foreach(Token t in noTypes) 924 foreach(Token t in noTypes)
1032 ErrorMsg(t, "looking for type"); 925 ErrorMsg(t, "looking for type");
1033 } 926 }
@@ -1048,11 +941,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1048 Token start = t; 941 Token start = t;
1049 string tnamestr = ((TokenName)t).val; 942 string tnamestr = ((TokenName)t).val;
1050 943
1051 /* 944 // Look for the name as a type declared by outerSDType or anything
1052 * Look for the name as a type declared by outerSDType or anything 945 // even farther out than that. If not found, simply return
1053 * even farther out than that. If not found, simply return 946 // without updating t, meaning that t isn't the name of a type.
1054 * without updating t, meaning that t isn't the name of a type.
1055 */
1056 TokenDeclSDType decl = null; 947 TokenDeclSDType decl = null;
1057 while(outerSDType != null) 948 while(outerSDType != null)
1058 { 949 {
@@ -1066,10 +957,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1066 TokenDeclSDType instdecl; 957 TokenDeclSDType instdecl;
1067 while(true) 958 while(true)
1068 { 959 {
1069 960 // If it is a generic type, it must be followed by instantiation arguments.
1070 /*
1071 * If it is a generic type, it must be followed by instantiation arguments.
1072 */
1073 instdecl = decl; 961 instdecl = decl;
1074 if(decl.genParams != null) 962 if(decl.genParams != null)
1075 { 963 {
@@ -1134,12 +1022,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1134 tokenScript.sdSrcTypesTryGetValue(tnamestr, out instdecl); 1022 tokenScript.sdSrcTypesTryGetValue(tnamestr, out instdecl);
1135 } 1023 }
1136 1024
1137 /* 1025 // Couldn't find 'List<string>' but found 'List' and we have genArgs = 'string'.
1138 * Couldn't find 'List<string>' but found 'List' and we have genArgs = 'string'. 1026 // Instantiate the generic to create 'List<string>'. This splices the definition
1139 * Instantiate the generic to create 'List<string>'. This splices the definition 1027 // of 'List<string>' into the source token stream just as if it had been there all
1140 * of 'List<string>' into the source token stream just as if it had been there all 1028 // along. We have to then repeat the scan to process the instance's contents.
1141 * along. We have to then repeat the scan to process the instance's contents.
1142 */
1143 if(instdecl == null) 1029 if(instdecl == null)
1144 { 1030 {
1145 instdecl = decl.InstantiateGeneric(tnamestr, genArgs, this); 1031 instdecl = decl.InstantiateGeneric(tnamestr, genArgs, this);
@@ -1148,9 +1034,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1148 } 1034 }
1149 } 1035 }
1150 1036
1151 /* 1037 // Maybe caller wants a subtype by putting a '.' following all that.
1152 * Maybe caller wants a subtype by putting a '.' following all that.
1153 */
1154 if(!(t.nextToken is TokenKwDot)) 1038 if(!(t.nextToken is TokenKwDot))
1155 break; 1039 break;
1156 if(!(t.nextToken.nextToken is TokenName)) 1040 if(!(t.nextToken.nextToken is TokenName))
@@ -1162,14 +1046,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1162 outerSDType = instdecl; 1046 outerSDType = instdecl;
1163 } 1047 }
1164 1048
1165 /* 1049 // Create a reference in the source to the definition
1166 * Create a reference in the source to the definition 1050 // that encapsulates the long dotted type name given in
1167 * that encapsulates the long dotted type name given in 1051 // the source, and replace the long dotted type name in
1168 * the source, and replace the long dotted type name in 1052 // the source with the reference token, eg, replace
1169 * the source with the reference token, eg, replace 1053 // 'Dictionary' '<' 'string' ',' 'integer' '>' '.' 'ValueList'
1170 * 'Dictionary' '<' 'string' ',' 'integer' '>' '.' 'ValueList' 1054 // with 'Dictionary<string,integer>.ValueList'.
1171 * with 'Dictionary<string,integer>.ValueList'.
1172 */
1173 TokenType refer = instdecl.MakeRefToken(start); 1055 TokenType refer = instdecl.MakeRefToken(start);
1174 if(refer == null) 1056 if(refer == null)
1175 { 1057 {
@@ -1203,11 +1085,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1203 1085
1204 Stack<int> ranks = new Stack<int>(); 1086 Stack<int> ranks = new Stack<int>();
1205 1087
1206 /* 1088 // When script specifies 'float[,][]' it means a two-dimensional matrix
1207 * When script specifies 'float[,][]' it means a two-dimensional matrix 1089 // that points to one-dimensional vectors of floats. So we would push
1208 * that points to one-dimensional vectors of floats. So we would push 1090 // a 2 then a 1 in this parsing code...
1209 * a 2 then a 1 in this parsing code...
1210 */
1211 do 1091 do
1212 { 1092 {
1213 t = t.nextToken; // point at '[' 1093 t = t.nextToken; // point at '['
@@ -1225,14 +1105,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1225 ranks.Push(rank); 1105 ranks.Push(rank);
1226 } while(t.nextToken is TokenKwBrkOpen); 1106 } while(t.nextToken is TokenKwBrkOpen);
1227 1107
1228 /* 1108 // Now we build the types in reverse order. For the example above we will:
1229 * Now we build the types in reverse order. For the example above we will: 1109 // first, create a type that is a one-dimensional vector of floats, float[]
1230 * first, create a type that is a one-dimensional vector of floats, float[] 1110 // second, create a type that is a two-dimensional matrix of that.
1231 * second, create a type that is a two-dimensional matrix of that. 1111 // This keeps declaration and referencing similar, eg,
1232 * This keeps declaration and referencing similar, eg, 1112 // float[,][] jag = new float[,][] (3,4);
1233 * float[,][] jag = new float[,][] (3,4); 1113 // jag[i,j][k] ... is used to access the elements
1234 * jag[i,j][k] ... is used to access the elements
1235 */
1236 do 1114 do
1237 { 1115 {
1238 int rank = ranks.Pop(); 1116 int rank = ranks.Pop();
@@ -1240,17 +1118,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1240 ofType = decl.MakeRefToken(ofType); 1118 ofType = decl.MakeRefToken(ofType);
1241 } while(ranks.Count > 0); 1119 } while(ranks.Count > 0);
1242 1120
1243 /* 1121 // Finally splice in the resultant array type to replace the original tokens.
1244 * Finally splice in the resultant array type to replace the original tokens.
1245 */
1246 ofType.prevToken = start.prevToken; 1122 ofType.prevToken = start.prevToken;
1247 ofType.nextToken = t.nextToken; 1123 ofType.nextToken = t.nextToken;
1248 ofType.prevToken.nextToken = ofType; 1124 ofType.prevToken.nextToken = ofType;
1249 ofType.nextToken.prevToken = ofType; 1125 ofType.nextToken.prevToken = ofType;
1250 1126
1251 /* 1127 // Resume parsing just after the spliced-in array type token.
1252 * Resume parsing just after the spliced-in array type token.
1253 */
1254 return ofType; 1128 return ofType;
1255 } 1129 }
1256 1130
@@ -1262,13 +1136,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1262 */ 1136 */
1263 private TokenDeclSDType InstantiateFixedArray(int rank, TokenType ofType, Token tokenBegin, ref uint repeat) 1137 private TokenDeclSDType InstantiateFixedArray(int rank, TokenType ofType, Token tokenBegin, ref uint repeat)
1264 { 1138 {
1265 /* 1139 // Create the array type's name.
1266 * Create the array type's name. 1140 // If starting with a non-array type, just append the rank to it, eg, float + rank=1 -> float[]
1267 * If starting with a non-array type, just append the rank to it, eg, float + rank=1 -> float[] 1141 // If starting with an array type, slip this rank in front of existing array, eg, float[] + rank=2 -> float[,][].
1268 * If starting with an array type, slip this rank in front of existing array, eg, float[] + rank=2 -> float[,][]. 1142 // This makes it consistent with what the script-writer sees for both a type specification and when
1269 * This makes it consistent with what the script-writer sees for both a type specification and when 1143 // referencing elements in a jagged array.
1270 * referencing elements in a jagged array.
1271 */
1272 string name = ofType.ToString(); 1144 string name = ofType.ToString();
1273 StringBuilder sb = new StringBuilder(name); 1145 StringBuilder sb = new StringBuilder(name);
1274 int ix = name.IndexOf('['); 1146 int ix = name.IndexOf('[');
@@ -1293,12 +1165,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1293 if(ofType is TokenTypeInt) 1165 if(ofType is TokenTypeInt)
1294 suffix = 'I'; 1166 suffix = 'I';
1295 1167
1296 /* 1168 // Don't already have one, create a new skeleton struct.
1297 * Don't already have one, create a new skeleton struct. 1169 // Splice in a definition for the class at beginning of source file.
1298 * Splice in a definition for the class at beginning of source file. 1170 //
1299 * 1171 // class <arraytypename> {
1300 * class <arraytypename> {
1301 */
1302 fa = new TokenDeclSDTypeClass(new TokenName(tokenScript, name), false); 1172 fa = new TokenDeclSDTypeClass(new TokenName(tokenScript, name), false);
1303 CatalogSDTypeDecl(fa); 1173 CatalogSDTypeDecl(fa);
1304 repeat |= REPEAT_INSTGEN; 1174 repeat |= REPEAT_INSTGEN;
@@ -1308,12 +1178,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1308 Token t = SpliceAfter(tokenBegin, fa); 1178 Token t = SpliceAfter(tokenBegin, fa);
1309 t = SpliceAfter(t, new TokenKwBrcOpen(t)); 1179 t = SpliceAfter(t, new TokenKwBrcOpen(t));
1310 1180
1311 /* 1181 // public integer len0;
1312 * public integer len0; 1182 // public integer len1;
1313 * public integer len1; 1183 // ...
1314 * ... 1184 // public object obj;
1315 * public object obj;
1316 */
1317 for(int i = 0; i < rank; i++) 1185 for(int i = 0; i < rank; i++)
1318 { 1186 {
1319 t = SpliceAfter(t, new TokenKwPublic(t)); 1187 t = SpliceAfter(t, new TokenKwPublic(t));
@@ -1327,14 +1195,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1327 t = SpliceAfter(t, new TokenName(t, "obj")); 1195 t = SpliceAfter(t, new TokenName(t, "obj"));
1328 t = SpliceAfter(t, new TokenKwSemi(t)); 1196 t = SpliceAfter(t, new TokenKwSemi(t));
1329 1197
1330 /* 1198 // public constructor (integer len0, integer len1, ...) {
1331 * public constructor (integer len0, integer len1, ...) { 1199 // this.len0 = len0;
1332 * this.len0 = len0; 1200 // this.len1 = len1;
1333 * this.len1 = len1; 1201 // ...
1334 * ... 1202 // this.obj = xmrFixedArrayAlloc<suffix> (len0 * len1 * ...);
1335 * this.obj = xmrFixedArrayAlloc<suffix> (len0 * len1 * ...); 1203 // }
1336 * }
1337 */
1338 t = SpliceAfter(t, new TokenKwPublic(t)); 1204 t = SpliceAfter(t, new TokenKwPublic(t));
1339 t = SpliceAfter(t, new TokenKwConstructor(t)); 1205 t = SpliceAfter(t, new TokenKwConstructor(t));
1340 t = SpliceAfter(t, new TokenKwParOpen(t)); 1206 t = SpliceAfter(t, new TokenKwParOpen(t));
@@ -1374,11 +1240,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1374 t = SpliceAfter(t, new TokenKwSemi(t)); 1240 t = SpliceAfter(t, new TokenKwSemi(t));
1375 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1241 t = SpliceAfter(t, new TokenKwBrcClose(t));
1376 1242
1377 /* 1243 // public integer Length { get {
1378 * public integer Length { get { 1244 // return this.len0 * this.len1 * ... ;
1379 * return this.len0 * this.len1 * ... ; 1245 // } }
1380 * } }
1381 */
1382 t = SpliceAfter(t, new TokenKwPublic(t)); 1246 t = SpliceAfter(t, new TokenKwPublic(t));
1383 t = SpliceAfter(t, new TokenTypeInt(t)); 1247 t = SpliceAfter(t, new TokenTypeInt(t));
1384 t = SpliceAfter(t, new TokenName(t, "Length")); 1248 t = SpliceAfter(t, new TokenName(t, "Length"));
@@ -1400,16 +1264,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1400 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1264 t = SpliceAfter(t, new TokenKwBrcClose(t));
1401 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1265 t = SpliceAfter(t, new TokenKwBrcClose(t));
1402 1266
1403 /* 1267 // public integer Length (integer dim) {
1404 * public integer Length (integer dim) { 1268 // switch (dim) {
1405 * switch (dim) { 1269 // case 0: return this.len0;
1406 * case 0: return this.len0; 1270 // case 1: return this.len1;
1407 * case 1: return this.len1; 1271 // ...
1408 * ... 1272 // }
1409 * } 1273 // return 0;
1410 * return 0; 1274 // }
1411 * }
1412 */
1413 t = SpliceAfter(t, new TokenKwPublic(t)); 1275 t = SpliceAfter(t, new TokenKwPublic(t));
1414 t = SpliceAfter(t, new TokenTypeInt(t)); 1276 t = SpliceAfter(t, new TokenTypeInt(t));
1415 t = SpliceAfter(t, new TokenName(t, "Length")); 1277 t = SpliceAfter(t, new TokenName(t, "Length"));
@@ -1443,15 +1305,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1443 t = SpliceAfter(t, new TokenKwSemi(t)); 1305 t = SpliceAfter(t, new TokenKwSemi(t));
1444 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1306 t = SpliceAfter(t, new TokenKwBrcClose(t));
1445 1307
1446 /* 1308 // public integer Index (integer idx0, integet idx1, ...) {
1447 * public integer Index (integer idx0, integet idx1, ...) { 1309 // integer idx = idx0;
1448 * integer idx = idx0; 1310 // idx *= this.len1; idx += idx1;
1449 * idx *= this.len1; idx += idx1; 1311 // idx *= this.len2; idx += idx2;
1450 * idx *= this.len2; idx += idx2; 1312 // ...
1451 * ... 1313 // return idx;
1452 * return idx; 1314 // }
1453 * }
1454 */
1455 t = SpliceAfter(t, new TokenKwPublic(t)); 1315 t = SpliceAfter(t, new TokenKwPublic(t));
1456 t = SpliceAfter(t, new TokenTypeInt(t)); 1316 t = SpliceAfter(t, new TokenTypeInt(t));
1457 t = SpliceAfter(t, new TokenName(t, "Index")); 1317 t = SpliceAfter(t, new TokenName(t, "Index"));
@@ -1491,15 +1351,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1491 t = SpliceAfter(t, new TokenKwSemi(t)); 1351 t = SpliceAfter(t, new TokenKwSemi(t));
1492 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1352 t = SpliceAfter(t, new TokenKwBrcClose(t));
1493 1353
1494 /* 1354 // public <oftype> Get (integer idx0, integet idx1, ...) {
1495 * public <oftype> Get (integer idx0, integet idx1, ...) { 1355 // integer idx = idx0;
1496 * integer idx = idx0; 1356 // idx *= this.len1; idx += idx1;
1497 * idx *= this.len1; idx += idx1; 1357 // idx *= this.len2; idx += idx2;
1498 * idx *= this.len2; idx += idx2; 1358 // ...
1499 * ... 1359 // return (<oftype>) xmrFixedArrayGet<suffix> (this.obj, idx);
1500 * return (<oftype>) xmrFixedArrayGet<suffix> (this.obj, idx); 1360 // }
1501 * }
1502 */
1503 t = SpliceAfter(t, new TokenKwPublic(t)); 1361 t = SpliceAfter(t, new TokenKwPublic(t));
1504 t = SpliceAfter(t, ofType.CopyToken(t)); 1362 t = SpliceAfter(t, ofType.CopyToken(t));
1505 t = SpliceAfter(t, new TokenName(t, "Get")); 1363 t = SpliceAfter(t, new TokenName(t, "Get"));
@@ -1552,15 +1410,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1552 t = SpliceAfter(t, new TokenKwSemi(t)); 1410 t = SpliceAfter(t, new TokenKwSemi(t));
1553 t = SpliceAfter(t, new TokenKwBrcClose(t)); 1411 t = SpliceAfter(t, new TokenKwBrcClose(t));
1554 1412
1555 /* 1413 // public void Set (integer idx0, integer idx1, ..., <oftype> val) {
1556 * public void Set (integer idx0, integer idx1, ..., <oftype> val) { 1414 // integer idx = idx0;
1557 * integer idx = idx0; 1415 // idx *= this.len1; idx += idx1;
1558 * idx *= this.len1; idx += idx1; 1416 // idx *= this.len2; idx += idx2;
1559 * idx *= this.len2; idx += idx2; 1417 // ...
1560 * ... 1418 // xmrFixedArraySet<suffix> (this.obj, idx, val);
1561 * xmrFixedArraySet<suffix> (this.obj, idx, val); 1419 // }
1562 * }
1563 */
1564 t = SpliceAfter(t, new TokenKwPublic(t)); 1420 t = SpliceAfter(t, new TokenKwPublic(t));
1565 t = SpliceAfter(t, new TokenTypeVoid(t)); 1421 t = SpliceAfter(t, new TokenTypeVoid(t));
1566 t = SpliceAfter(t, new TokenName(t, "Set")); 1422 t = SpliceAfter(t, new TokenName(t, "Set"));
@@ -1764,10 +1620,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1764 tokdeclcl.members.thisClass = tokdeclcl; 1620 tokdeclcl.members.thisClass = tokdeclcl;
1765 tokenScript.PushVarFrame(tokdeclcl.members); 1621 tokenScript.PushVarFrame(tokdeclcl.members);
1766 1622
1767 /* 1623 // Create a function $instfieldnit to hold all explicit
1768 * Create a function $instfieldnit to hold all explicit 1624 // instance field initializations.
1769 * instance field initializations.
1770 */
1771 TokenDeclVar ifiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); 1625 TokenDeclVar ifiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript);
1772 ifiFunc.name = new TokenName(ifiFunc, "$instfieldinit"); 1626 ifiFunc.name = new TokenName(ifiFunc, "$instfieldinit");
1773 ifiFunc.retType = new TokenTypeVoid(ifiFunc); 1627 ifiFunc.retType = new TokenTypeVoid(ifiFunc);
@@ -1780,10 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1780 tokdeclcl.instFieldInit = ifiFunc; 1634 tokdeclcl.instFieldInit = ifiFunc;
1781 tokenScript.AddVarEntry(ifiFunc); 1635 tokenScript.AddVarEntry(ifiFunc);
1782 1636
1783 /* 1637 // Create a function $staticfieldnit to hold all explicit
1784 * Create a function $staticfieldnit to hold all explicit 1638 // static field initializations.
1785 * static field initializations.
1786 */
1787 TokenDeclVar sfiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); 1639 TokenDeclVar sfiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript);
1788 sfiFunc.name = new TokenName(sfiFunc, "$staticfieldinit"); 1640 sfiFunc.name = new TokenName(sfiFunc, "$staticfieldinit");
1789 sfiFunc.retType = new TokenTypeVoid(sfiFunc); 1641 sfiFunc.retType = new TokenTypeVoid(sfiFunc);
@@ -1805,25 +1657,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1805 continue; 1657 continue;
1806 } 1658 }
1807 1659
1808 /* 1660 // Check for all qualifiers.
1809 * Check for all qualifiers. 1661 // typedef has an implied 'public' qualifier.
1810 * typedef has an implied 'public' qualifier.
1811 */
1812 flags = SDT_PUBLIC; 1662 flags = SDT_PUBLIC;
1813 if(!(token is TokenDeclSDTypeTypedef)) 1663 if(!(token is TokenDeclSDTypeTypedef))
1814 { 1664 {
1815 flags = ParseQualifierFlags(ref token); 1665 flags = ParseQualifierFlags(ref token);
1816 } 1666 }
1817 1667
1818 /* 1668 // Parse nested script-defined type definitions.
1819 * Parse nested script-defined type definitions.
1820 */
1821 if(ParseDeclSDTypes(ref token, tokdeclcl, flags)) 1669 if(ParseDeclSDTypes(ref token, tokdeclcl, flags))
1822 continue; 1670 continue;
1823 1671
1824 /* 1672 // constant <name> = <rval> ;
1825 * constant <name> = <rval> ;
1826 */
1827 if(token is TokenKwConst) 1673 if(token is TokenKwConst)
1828 { 1674 {
1829 if((flags & (SDT_ABSTRACT | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0) 1675 if((flags & (SDT_ABSTRACT | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0)
@@ -1839,10 +1685,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1839 continue; 1685 continue;
1840 } 1686 }
1841 1687
1842 /* 1688 // <type> <name> ;
1843 * <type> <name> ; 1689 // <type> <name> = <rval> ;
1844 * <type> <name> = <rval> ;
1845 */
1846 if((token is TokenType) && 1690 if((token is TokenType) &&
1847 (token.nextToken is TokenName) && 1691 (token.nextToken is TokenName) &&
1848 ((token.nextToken.nextToken is TokenKwSemi) || 1692 ((token.nextToken.nextToken is TokenKwSemi) ||
@@ -1877,10 +1721,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1877 continue; 1721 continue;
1878 } 1722 }
1879 1723
1880 /* 1724 // <type> <name> [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] }
1881 * <type> <name> [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] } 1725 // <type> '[' ... ']' [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] }
1882 * <type> '[' ... ']' [ : <implintfs> ] { [ get { <body> } ] [ set { <body> } ] }
1883 */
1884 bool prop = (token is TokenType) && 1726 bool prop = (token is TokenType) &&
1885 (token.nextToken is TokenName) && 1727 (token.nextToken is TokenName) &&
1886 (token.nextToken.nextToken is TokenKwBrcOpen || 1728 (token.nextToken.nextToken is TokenKwBrcOpen ||
@@ -1907,9 +1749,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1907 continue; 1749 continue;
1908 } 1750 }
1909 1751
1910 /* 1752 // 'constructor' '(' arglist ')' [ ':' [ 'base' ] '(' baseconstructorcall ')' ] '{' body '}'
1911 * 'constructor' '(' arglist ')' [ ':' [ 'base' ] '(' baseconstructorcall ')' ] '{' body '}'
1912 */
1913 if(token is TokenKwConstructor) 1753 if(token is TokenKwConstructor)
1914 { 1754 {
1915 ParseSDTClassCtorDecl(ref token, flags, tokdeclcl); 1755 ParseSDTClassCtorDecl(ref token, flags, tokdeclcl);
@@ -1917,36 +1757,28 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1917 continue; 1757 continue;
1918 } 1758 }
1919 1759
1920 /* 1760 // <type> <name> <funcargs> <funcbody>
1921 * <type> <name> <funcargs> <funcbody> 1761 // method with explicit return type
1922 * method with explicit return type
1923 */
1924 if(token is TokenType) 1762 if(token is TokenType)
1925 { 1763 {
1926 ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); 1764 ParseSDTClassMethodDecl(ref token, flags, tokdeclcl);
1927 continue; 1765 continue;
1928 } 1766 }
1929 1767
1930 /* 1768 // <name> <funcargs> <funcbody>
1931 * <name> <funcargs> <funcbody> 1769 // method returning void
1932 * method returning void
1933 */
1934 if((token is TokenName) || ((token is TokenKw) && ((TokenKw)token).sdtClassOp)) 1770 if((token is TokenName) || ((token is TokenKw) && ((TokenKw)token).sdtClassOp))
1935 { 1771 {
1936 ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); 1772 ParseSDTClassMethodDecl(ref token, flags, tokdeclcl);
1937 continue; 1773 continue;
1938 } 1774 }
1939 1775
1940 /* 1776 // That's all we support in a class declaration.
1941 * That's all we support in a class declaration.
1942 */
1943 ErrorMsg(token, "expecting field or method declaration"); 1777 ErrorMsg(token, "expecting field or method declaration");
1944 token = SkipPastSemi(token); 1778 token = SkipPastSemi(token);
1945 } 1779 }
1946 1780
1947 /* 1781 // If script didn't specify any constructor, create a default no-argument one.
1948 * If script didn't specify any constructor, create a default no-argument one.
1949 */
1950 if(!haveExplicitConstructor) 1782 if(!haveExplicitConstructor)
1951 { 1783 {
1952 TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript); 1784 TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript);
@@ -1971,9 +1803,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1971 tokenScript.AddVarEntry(tokenDeclFunc); 1803 tokenScript.AddVarEntry(tokenDeclFunc);
1972 } 1804 }
1973 1805
1974 /* 1806 // Skip over the closing brace and pop corresponding var frame.
1975 * Skip over the closing brace and pop corresponding var frame.
1976 */
1977 token = token.nextToken; 1807 token = token.nextToken;
1978 tokenScript.PopVarFrame(); 1808 tokenScript.PopVarFrame();
1979 ret: 1809 ret:
@@ -2079,10 +1909,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2079 */ 1909 */
2080 private TokenDeclVar ParseProperty(ref Token token, bool abs, bool imp) 1910 private TokenDeclVar ParseProperty(ref Token token, bool abs, bool imp)
2081 { 1911 {
2082 /* 1912 // Parse out the property's type and name.
2083 * Parse out the property's type and name. 1913 // <type> <name>
2084 * <type> <name>
2085 */
2086 TokenType type = (TokenType)token; 1914 TokenType type = (TokenType)token;
2087 TokenName name; 1915 TokenName name;
2088 TokenArgDecl args; 1916 TokenArgDecl args;
@@ -2101,10 +1929,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2101 args = new TokenArgDecl(token); 1929 args = new TokenArgDecl(token);
2102 } 1930 }
2103 1931
2104 /* 1932 // Maybe it claims to implement some interface properties.
2105 * Maybe it claims to implement some interface properties. 1933 // [ ':' <ifacetype>[.<propname>] ',' ... ]
2106 * [ ':' <ifacetype>[.<propname>] ',' ... ]
2107 */
2108 TokenIntfImpl implements = null; 1934 TokenIntfImpl implements = null;
2109 if(token is TokenKwColon) 1935 if(token is TokenKwColon)
2110 { 1936 {
@@ -2117,9 +1943,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2117 } 1943 }
2118 } 1944 }
2119 1945
2120 /* 1946 // Should have an opening brace.
2121 * Should have an opening brace.
2122 */
2123 if(!(token is TokenKwBrcOpen)) 1947 if(!(token is TokenKwBrcOpen))
2124 { 1948 {
2125 ErrorMsg(token, "expect { to open property definition"); 1949 ErrorMsg(token, "expect { to open property definition");
@@ -2128,19 +1952,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2128 } 1952 }
2129 token = token.nextToken; 1953 token = token.nextToken;
2130 1954
2131 /* 1955 // Parse out the getter and/or setter.
2132 * Parse out the getter and/or setter. 1956 // 'get' { <body> | ';' }
2133 * 'get' { <body> | ';' } 1957 // 'set' { <body> | ';' }
2134 * 'set' { <body> | ';' }
2135 */
2136 TokenDeclVar getFunc = null; 1958 TokenDeclVar getFunc = null;
2137 TokenDeclVar setFunc = null; 1959 TokenDeclVar setFunc = null;
2138 while(!(token is TokenKwBrcClose)) 1960 while(!(token is TokenKwBrcClose))
2139 { 1961 {
2140 1962 // Maybe create a getter function.
2141 /*
2142 * Maybe create a getter function.
2143 */
2144 if(token is TokenKwGet) 1963 if(token is TokenKwGet)
2145 { 1964 {
2146 getFunc = new TokenDeclVar(token, null, tokenScript); 1965 getFunc = new TokenDeclVar(token, null, tokenScript);
@@ -2161,9 +1980,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2161 continue; 1980 continue;
2162 } 1981 }
2163 1982
2164 /* 1983 // Maybe create a setter function.
2165 * Maybe create a setter function.
2166 */
2167 if(token is TokenKwSet) 1984 if(token is TokenKwSet)
2168 { 1985 {
2169 TokenArgDecl argDecl = args; 1986 TokenArgDecl argDecl = args;
@@ -2204,18 +2021,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2204 return null; 2021 return null;
2205 } 2022 }
2206 2023
2207 /* 2024 // Set up a variable for the property.
2208 * Set up a variable for the property.
2209 */
2210 TokenDeclVar tokenDeclVar = new TokenDeclVar(name, null, tokenScript); 2025 TokenDeclVar tokenDeclVar = new TokenDeclVar(name, null, tokenScript);
2211 tokenDeclVar.type = type; 2026 tokenDeclVar.type = type;
2212 tokenDeclVar.name = name; 2027 tokenDeclVar.name = name;
2213 tokenDeclVar.getProp = getFunc; 2028 tokenDeclVar.getProp = getFunc;
2214 tokenDeclVar.setProp = setFunc; 2029 tokenDeclVar.setProp = setFunc;
2215 2030
2216 /* 2031 // Can't be same name already in block.
2217 * Can't be same name already in block.
2218 */
2219 if(!tokenScript.AddVarEntry(tokenDeclVar)) 2032 if(!tokenScript.AddVarEntry(tokenDeclVar))
2220 { 2033 {
2221 ErrorMsg(tokenDeclVar, "duplicate member " + name.val); 2034 ErrorMsg(tokenDeclVar, "duplicate member " + name.val);
@@ -2279,17 +2092,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2279 tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); 2092 tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict);
2280 try 2093 try
2281 { 2094 {
2282 /* 2095 // Set up reference to base constructor.
2283 * Set up reference to base constructor.
2284 */
2285 TokenLValBaseField baseCtor = new TokenLValBaseField(token, 2096 TokenLValBaseField baseCtor = new TokenLValBaseField(token,
2286 new TokenName(token, "$ctor"), 2097 new TokenName(token, "$ctor"),
2287 tokdeclcl); 2098 tokdeclcl);
2288 2099
2289 /* 2100 // Parse any base constructor call as if it were the first statement of the
2290 * Parse any base constructor call as if it were the first statement of the 2101 // constructor itself.
2291 * constructor itself.
2292 */
2293 if(token is TokenKwColon) 2102 if(token is TokenKwColon)
2294 { 2103 {
2295 token = token.nextToken; 2104 token = token.nextToken;
@@ -2318,17 +2127,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2318 } 2127 }
2319 else if(tokdeclcl.extends != null) 2128 else if(tokdeclcl.extends != null)
2320 { 2129 {
2321 2130 // Caller didn't specify a constructor but we are extending, so we will
2322 /* 2131 // call the extended class's default constructor.
2323 * Caller didn't specify a constructor but we are extending, so we will
2324 * call the extended class's default constructor.
2325 */
2326 SetUpDefaultBaseCtorCall(tokenDeclFunc); 2132 SetUpDefaultBaseCtorCall(tokenDeclFunc);
2327 } 2133 }
2328 2134
2329 /* 2135 // Parse the constructor body.
2330 * Parse the constructor body.
2331 */
2332 tokenDeclFunc.body = ParseStmtBlock(ref token); 2136 tokenDeclFunc.body = ParseStmtBlock(ref token);
2333 if(tokenDeclFunc.body == null) 2137 if(tokenDeclFunc.body == null)
2334 return; 2138 return;
@@ -2341,10 +2145,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2341 currentDeclFunc = saveDeclFunc; 2145 currentDeclFunc = saveDeclFunc;
2342 } 2146 }
2343 2147
2344 /* 2148 // Add to list of methods defined by this class.
2345 * Add to list of methods defined by this class. 2149 // It has the name "$ctor(argsig)".
2346 * It has the name "$ctor(argsig)".
2347 */
2348 if(!tokenScript.AddVarEntry(tokenDeclFunc)) 2150 if(!tokenScript.AddVarEntry(tokenDeclFunc))
2349 { 2151 {
2350 ErrorMsg(tokenDeclFunc, "duplicate constructor definition"); 2152 ErrorMsg(tokenDeclFunc, "duplicate constructor definition");
@@ -2443,7 +2245,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2443 } 2245 }
2444 else 2246 else
2445 { 2247 {
2446
2447 // other times should have ',' <type> 2248 // other times should have ',' <type>
2448 if(!(u is TokenKwComma)) 2249 if(!(u is TokenKwComma))
2449 { 2250 {
@@ -2550,16 +2351,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2550 continue; 2351 continue;
2551 } 2352 }
2552 2353
2553 /* 2354 // Parse nested script-defined type definitions.
2554 * Parse nested script-defined type definitions.
2555 */
2556 if(ParseDeclSDTypes(ref token, tokdeclin, SDT_PUBLIC)) 2355 if(ParseDeclSDTypes(ref token, tokdeclin, SDT_PUBLIC))
2557 continue; 2356 continue;
2558 2357
2559 /* 2358 // <type> <name> <funcargs> ;
2560 * <type> <name> <funcargs> ; 2359 // abstract method with explicit return type
2561 * abstract method with explicit return type
2562 */
2563 if((token is TokenType) && 2360 if((token is TokenType) &&
2564 (token.nextToken is TokenName) && 2361 (token.nextToken is TokenName) &&
2565 (token.nextToken.nextToken is TokenKwParOpen)) 2362 (token.nextToken.nextToken is TokenKwParOpen))
@@ -2576,10 +2373,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2576 continue; 2373 continue;
2577 } 2374 }
2578 2375
2579 /* 2376 // <name> <funcargs> ;
2580 * <name> <funcargs> ; 2377 // abstract method returning void
2581 * abstract method returning void
2582 */
2583 if((token is TokenName) && 2378 if((token is TokenName) &&
2584 (token.nextToken is TokenKwParOpen)) 2379 (token.nextToken is TokenKwParOpen))
2585 { 2380 {
@@ -2594,11 +2389,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2594 continue; 2389 continue;
2595 } 2390 }
2596 2391
2597 /* 2392 // <type> <name> { [ get ; ] [ set ; ] }
2598 * <type> <name> { [ get ; ] [ set ; ] } 2393 // <type> '[' ... ']' { [ get ; ] [ set ; ] }
2599 * <type> '[' ... ']' { [ get ; ] [ set ; ] } 2394 // abstract property
2600 * abstract property
2601 */
2602 bool prop = (token is TokenType) && 2395 bool prop = (token is TokenType) &&
2603 (token.nextToken is TokenName) && 2396 (token.nextToken is TokenName) &&
2604 (token.nextToken.nextToken is TokenKwBrcOpen || 2397 (token.nextToken.nextToken is TokenKwBrcOpen ||
@@ -2610,16 +2403,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2610 continue; 2403 continue;
2611 } 2404 }
2612 2405
2613 /* 2406 // That's all we support in an interface declaration.
2614 * That's all we support in an interface declaration.
2615 */
2616 ErrorMsg(token, "expecting method or property prototype"); 2407 ErrorMsg(token, "expecting method or property prototype");
2617 token = SkipPastSemi(token); 2408 token = SkipPastSemi(token);
2618 } 2409 }
2619 2410
2620 /* 2411 // Skip over the closing brace and pop the corresponding var frame.
2621 * Skip over the closing brace and pop the corresponding var frame.
2622 */
2623 token = token.nextToken; 2412 token = token.nextToken;
2624 tokenScript.PopVarFrame(); 2413 tokenScript.PopVarFrame();
2625 } 2414 }
@@ -2807,29 +2596,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2807 return true; 2596 return true;
2808 } 2597 }
2809 2598
2810 /* 2599 // Declare this function as being the one currently being processed
2811 * Declare this function as being the one currently being processed 2600 // for anything that cares. We also start a variable frame that
2812 * for anything that cares. We also start a variable frame that 2601 // includes all the declared parameters.
2813 * includes all the declared parameters.
2814 */
2815 TokenDeclVar saveDeclFunc = currentDeclFunc; 2602 TokenDeclVar saveDeclFunc = currentDeclFunc;
2816 currentDeclFunc = tokenDeclFunc; 2603 currentDeclFunc = tokenDeclFunc;
2817 tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); 2604 tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict);
2818 2605
2819 /* 2606 // Now parse the function statement block.
2820 * Now parse the function statement block.
2821 */
2822 tokenDeclFunc.body = ParseStmtBlock(ref token); 2607 tokenDeclFunc.body = ParseStmtBlock(ref token);
2823 2608
2824 /* 2609 // Pop the var frame that contains the arguments.
2825 * Pop the var frame that contains the arguments.
2826 */
2827 tokenScript.PopVarFrame(); 2610 tokenScript.PopVarFrame();
2828 currentDeclFunc = saveDeclFunc; 2611 currentDeclFunc = saveDeclFunc;
2829 2612
2830 /* 2613 // Check final errors.
2831 * Check final errors.
2832 */
2833 if(tokenDeclFunc.body == null) 2614 if(tokenDeclFunc.body == null)
2834 return false; 2615 return false;
2835 if(abs) 2616 if(abs)
@@ -2851,9 +2632,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2851 */ 2632 */
2852 private TokenStmt ParseStmt(ref Token token) 2633 private TokenStmt ParseStmt(ref Token token)
2853 { 2634 {
2854 /* 2635 // Statements that begin with a specific keyword.
2855 * Statements that begin with a specific keyword.
2856 */
2857 if(token is TokenKwAt) 2636 if(token is TokenKwAt)
2858 return ParseStmtLabel(ref token); 2637 return ParseStmtLabel(ref token);
2859 if(token is TokenKwBrcOpen) 2638 if(token is TokenKwBrcOpen)
@@ -2887,10 +2666,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2887 if(token is TokenKwWhile) 2666 if(token is TokenKwWhile)
2888 return ParseStmtWhile(ref token); 2667 return ParseStmtWhile(ref token);
2889 2668
2890 /* 2669 // Try to parse anything else as an expression, possibly calling
2891 * Try to parse anything else as an expression, possibly calling 2670 // something and/or writing to a variable.
2892 * something and/or writing to a variable.
2893 */
2894 TokenRVal tokenRVal = ParseRVal(ref token, semiOnly); 2671 TokenRVal tokenRVal = ParseRVal(ref token, semiOnly);
2895 if(tokenRVal != null) 2672 if(tokenRVal != null)
2896 { 2673 {
@@ -2899,9 +2676,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2899 return tokenStmtRVal; 2676 return tokenStmtRVal;
2900 } 2677 }
2901 2678
2902 /* 2679 // Who knows what it is...
2903 * Who knows what it is...
2904 */
2905 ErrorMsg(token, "unknown statement"); 2680 ErrorMsg(token, "unknown statement");
2906 token = SkipPastSemi(token); 2681 token = SkipPastSemi(token);
2907 return null; 2682 return null;
@@ -3053,9 +2828,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3053 { 2828 {
3054 currentDeclFunc.triviality = Triviality.complex; 2829 currentDeclFunc.triviality = Triviality.complex;
3055 2830
3056 /* 2831 // Create encapsulating token and skip past 'for ('
3057 * Create encapsulating token and skip past 'for ('
3058 */
3059 TokenStmtFor tokenStmtFor = new TokenStmtFor(token); 2832 TokenStmtFor tokenStmtFor = new TokenStmtFor(token);
3060 token = token.nextToken; 2833 token = token.nextToken;
3061 if(!(token is TokenKwParOpen)) 2834 if(!(token is TokenKwParOpen))
@@ -3065,9 +2838,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3065 } 2838 }
3066 token = token.nextToken; 2839 token = token.nextToken;
3067 2840
3068 /* 2841 // If a plain for, ie, not declaring a variable, it's straightforward.
3069 * If a plain for, ie, not declaring a variable, it's straightforward.
3070 */
3071 if(!(token is TokenType)) 2842 if(!(token is TokenType))
3072 { 2843 {
3073 tokenStmtFor.initStmt = ParseStmt(ref token); 2844 tokenStmtFor.initStmt = ParseStmt(ref token);
@@ -3076,10 +2847,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3076 return ParseStmtFor2(tokenStmtFor, ref token) ? tokenStmtFor : null; 2847 return ParseStmtFor2(tokenStmtFor, ref token) ? tokenStmtFor : null;
3077 } 2848 }
3078 2849
3079 /* 2850 // Initialization declares a variable, so encapsulate it in a block so
3080 * Initialization declares a variable, so encapsulate it in a block so 2851 // variable has scope only in the for statement, including its body.
3081 * variable has scope only in the for statement, including its body.
3082 */
3083 TokenStmtBlock forStmtBlock = new TokenStmtBlock(tokenStmtFor); 2852 TokenStmtBlock forStmtBlock = new TokenStmtBlock(tokenStmtFor);
3084 forStmtBlock.outerStmtBlock = currentStmtBlock; 2853 forStmtBlock.outerStmtBlock = currentStmtBlock;
3085 forStmtBlock.function = currentDeclFunc; 2854 forStmtBlock.function = currentDeclFunc;
@@ -3148,9 +2917,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3148 { 2917 {
3149 currentDeclFunc.triviality = Triviality.complex; 2918 currentDeclFunc.triviality = Triviality.complex;
3150 2919
3151 /* 2920 // Create encapsulating token and skip past 'foreach ('
3152 * Create encapsulating token and skip past 'foreach ('
3153 */
3154 TokenStmtForEach tokenStmtForEach = new TokenStmtForEach(token); 2921 TokenStmtForEach tokenStmtForEach = new TokenStmtForEach(token);
3155 token = token.nextToken; 2922 token = token.nextToken;
3156 if(!(token is TokenKwParOpen)) 2923 if(!(token is TokenKwParOpen))
@@ -3222,9 +2989,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3222 2989
3223 private TokenStmtJump ParseStmtJump(ref Token token) 2990 private TokenStmtJump ParseStmtJump(ref Token token)
3224 { 2991 {
3225 /* 2992 // Create jump statement token to encapsulate the whole statement.
3226 * Create jump statement token to encapsulate the whole statement.
3227 */
3228 TokenStmtJump tokenStmtJump = new TokenStmtJump(token); 2993 TokenStmtJump tokenStmtJump = new TokenStmtJump(token);
3229 token = token.nextToken; 2994 token = token.nextToken;
3230 if(!(token is TokenName) || !(token.nextToken is TokenKwSemi)) 2995 if(!(token is TokenName) || !(token.nextToken is TokenKwSemi))
@@ -3236,11 +3001,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3236 tokenStmtJump.label = (TokenName)token; 3001 tokenStmtJump.label = (TokenName)token;
3237 token = token.nextToken.nextToken; 3002 token = token.nextToken.nextToken;
3238 3003
3239 /* 3004 // If label is already defined, it means this is a backward (looping)
3240 * If label is already defined, it means this is a backward (looping) 3005 // jump, so remember the label has backward jump references.
3241 * jump, so remember the label has backward jump references. 3006 // We also then assume the function is complex, ie, it has a loop.
3242 * We also then assume the function is complex, ie, it has a loop.
3243 */
3244 if(currentDeclFunc.labels.ContainsKey(tokenStmtJump.label.val)) 3007 if(currentDeclFunc.labels.ContainsKey(tokenStmtJump.label.val))
3245 { 3008 {
3246 currentDeclFunc.labels[tokenStmtJump.label.val].hasBkwdRefs = true; 3009 currentDeclFunc.labels[tokenStmtJump.label.val].hasBkwdRefs = true;
@@ -3450,9 +3213,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3450 */ 3213 */
3451 private TokenStmtTry ParseStmtTry(ref Token token) 3214 private TokenStmtTry ParseStmtTry(ref Token token)
3452 { 3215 {
3453 /* 3216 // Parse out the 'try { ... }' part
3454 * Parse out the 'try { ... }' part
3455 */
3456 Token tryKw = token; 3217 Token tryKw = token;
3457 token = token.nextToken; 3218 token = token.nextToken;
3458 TokenStmt body = ParseStmtBlock(ref token); 3219 TokenStmt body = ParseStmtBlock(ref token);
@@ -3585,14 +3346,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3585 { 3346 {
3586 TokenDeclVar tokenDeclVar = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript); 3347 TokenDeclVar tokenDeclVar = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript);
3587 3348
3588 /* 3349 // Handle constant declaration.
3589 * Handle constant declaration. 3350 // It ends up in the declared variables list for the statement block just like
3590 * It ends up in the declared variables list for the statement block just like 3351 // any other variable, except it has .constant = true.
3591 * any other variable, except it has .constant = true. 3352 // The code generator will test that the initialization expression is constant.
3592 * The code generator will test that the initialization expression is constant. 3353 //
3593 * 3354 // constant <name> = <value> ;
3594 * constant <name> = <value> ;
3595 */
3596 if(token is TokenKwConst) 3355 if(token is TokenKwConst)
3597 { 3356 {
3598 token = token.nextToken; 3357 token = token.nextToken;
@@ -3618,14 +3377,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3618 tokenDeclVar.constant = true; 3377 tokenDeclVar.constant = true;
3619 } 3378 }
3620 3379
3621 /* 3380 // Otherwise, normal variable declaration with optional initialization value.
3622 * Otherwise, normal variable declaration with optional initialization value.
3623 */
3624 else 3381 else
3625 { 3382 {
3626 /* 3383 // Build basic encapsulating token with type and name.
3627 * Build basic encapsulating token with type and name.
3628 */
3629 tokenDeclVar.type = (TokenType)token; 3384 tokenDeclVar.type = (TokenType)token;
3630 token = token.nextToken; 3385 token = token.nextToken;
3631 if(!(token is TokenName)) 3386 if(!(token is TokenName))
@@ -3637,10 +3392,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3637 tokenDeclVar.name = (TokenName)token; 3392 tokenDeclVar.name = (TokenName)token;
3638 token = token.nextToken; 3393 token = token.nextToken;
3639 3394
3640 /* 3395 // If just a ;, there is no explicit initialization value.
3641 * If just a ;, there is no explicit initialization value. 3396 // Otherwise, look for an =RVal; expression that has init value.
3642 * Otherwise, look for an =RVal; expression that has init value.
3643 */
3644 if(token is TokenKwSemi) 3397 if(token is TokenKwSemi)
3645 { 3398 {
3646 token = token.nextToken; 3399 token = token.nextToken;
@@ -3673,18 +3426,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3673 } 3426 }
3674 } 3427 }
3675 3428
3676 /* 3429 // If doing local vars, each var goes in its own var frame,
3677 * If doing local vars, each var goes in its own var frame, 3430 // to make sure no code before this point can reference it.
3678 * to make sure no code before this point can reference it.
3679 */
3680 if(currentStmtBlock != null) 3431 if(currentStmtBlock != null)
3681 { 3432 {
3682 tokenScript.PushVarFrame(true); 3433 tokenScript.PushVarFrame(true);
3683 } 3434 }
3684 3435
3685 /* 3436 // Can't be same name already in block.
3686 * Can't be same name already in block.
3687 */
3688 if(!tokenScript.AddVarEntry(tokenDeclVar)) 3437 if(!tokenScript.AddVarEntry(tokenDeclVar))
3689 { 3438 {
3690 ErrorMsg(tokenDeclVar, "duplicate variable " + tokenDeclVar.name.val); 3439 ErrorMsg(tokenDeclVar, "duplicate variable " + tokenDeclVar.name.val);
@@ -3702,9 +3451,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3702 */ 3451 */
3703 private void DoVarInit(TokenDeclVar initFunc, TokenLVal left, TokenRVal init) 3452 private void DoVarInit(TokenDeclVar initFunc, TokenLVal left, TokenRVal init)
3704 { 3453 {
3705 /* 3454 // Make a statement that assigns the initialization value to the variable.
3706 * Make a statement that assigns the initialization value to the variable.
3707 */
3708 TokenStmt stmt; 3455 TokenStmt stmt;
3709 if(init == null) 3456 if(init == null)
3710 { 3457 {
@@ -3720,11 +3467,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3720 stmt = tsrv; 3467 stmt = tsrv;
3721 } 3468 }
3722 3469
3723 /* 3470 // Add statement to end of initialization function.
3724 * Add statement to end of initialization function. 3471 // Be sure to execute them in same order as in source
3725 * Be sure to execute them in same order as in source 3472 // as some doofus scripts depend on it.
3726 * as some doofus scripts depend on it.
3727 */
3728 Token lastStmt = initFunc.body.statements; 3473 Token lastStmt = initFunc.body.statements;
3729 if(lastStmt == null) 3474 if(lastStmt == null)
3730 { 3475 {
@@ -3805,17 +3550,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3805 */ 3550 */
3806 public TokenRVal ParseRVal(ref Token token, Type[] termTokenTypes) 3551 public TokenRVal ParseRVal(ref Token token, Type[] termTokenTypes)
3807 { 3552 {
3808 /* 3553 // Start with pushing the first operand on operand stack.
3809 * Start with pushing the first operand on operand stack.
3810 */
3811 BinOp binOps = null; 3554 BinOp binOps = null;
3812 TokenRVal operands = GetOperand(ref token); 3555 TokenRVal operands = GetOperand(ref token);
3813 if(operands == null) 3556 if(operands == null)
3814 return null; 3557 return null;
3815 3558
3816 /* 3559 // Keep scanning until we hit the termination token.
3817 * Keep scanning until we hit the termination token.
3818 */
3819 while(true) 3560 while(true)
3820 { 3561 {
3821 Type tokType = token.GetType(); 3562 Type tokType = token.GetType();
@@ -3825,59 +3566,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3825 goto done; 3566 goto done;
3826 } 3567 }
3827 3568
3828 /* 3569 // Special form:
3829 * Special form: 3570 // <operand> is <typeexp>
3830 * <operand> is <typeexp>
3831 */
3832 if(token is TokenKwIs) 3571 if(token is TokenKwIs)
3833 { 3572 {
3834 TokenRValIsType tokenRValIsType = new TokenRValIsType(token); 3573 TokenRValIsType tokenRValIsType = new TokenRValIsType(token);
3835 token = token.nextToken; 3574 token = token.nextToken;
3836 3575
3837 /* 3576 // Parse the <typeexp>.
3838 * Parse the <typeexp>.
3839 */
3840 tokenRValIsType.typeExp = ParseTypeExp(ref token); 3577 tokenRValIsType.typeExp = ParseTypeExp(ref token);
3841 if(tokenRValIsType.typeExp == null) 3578 if(tokenRValIsType.typeExp == null)
3842 return null; 3579 return null;
3843 3580
3844 /* 3581 // Replace top operand with result of <operand> is <typeexp>
3845 * Replace top operand with result of <operand> is <typeexp>
3846 */
3847 tokenRValIsType.rValExp = operands; 3582 tokenRValIsType.rValExp = operands;
3848 tokenRValIsType.nextToken = operands.nextToken; 3583 tokenRValIsType.nextToken = operands.nextToken;
3849 operands = tokenRValIsType; 3584 operands = tokenRValIsType;
3850 3585
3851 /* 3586 // token points just past <typeexp> so see if it is another operator.
3852 * token points just past <typeexp> so see if it is another operator.
3853 */
3854 continue; 3587 continue;
3855 } 3588 }
3856 3589
3857 /* 3590 // Peek at next operator.
3858 * Peek at next operator.
3859 */
3860 BinOp binOp = GetOperator(ref token); 3591 BinOp binOp = GetOperator(ref token);
3861 if(binOp == null) 3592 if(binOp == null)
3862 return null; 3593 return null;
3863 3594
3864 /* 3595 // If there are stacked operators of higher or same precedence than new one,
3865 * If there are stacked operators of higher or same precedence than new one, 3596 // perform their computation then push result back on operand stack.
3866 * perform their computation then push result back on operand stack. 3597 //
3867 * 3598 // higher or same = left-to-right application of operators
3868 * higher or same = left-to-right application of operators 3599 // eg, a - b - c becomes (a - b) - c
3869 * eg, a - b - c becomes (a - b) - c 3600 //
3870 * 3601 // higher precedence = right-to-left application of operators
3871 * higher precedence = right-to-left application of operators 3602 // eg, a - b - c becomes a - (b - c)
3872 * eg, a - b - c becomes a - (b - c) 3603 //
3873 * 3604 // Now of course, there is some ugliness necessary:
3874 * Now of course, there is some ugliness necessary: 3605 // we want: a - b - c => (a - b) - c so we do 'higher or same'
3875 * we want: a - b - c => (a - b) - c so we do 'higher or same' 3606 // but we want: a += b = c => a += (b = c) so we do 'higher only'
3876 * but we want: a += b = c => a += (b = c) so we do 'higher only' 3607 //
3877 * 3608 // binOps is the first operator (or null if only one)
3878 * binOps is the first operator (or null if only one) 3609 // binOp is the second operator (or first if only one)
3879 * binOp is the second operator (or first if only one)
3880 */
3881 while(binOps != null) 3610 while(binOps != null)
3882 { 3611 {
3883 if(binOps.preced < binOp.preced) 3612 if(binOps.preced < binOp.preced)
@@ -3894,10 +3623,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3894 binOps = binOps.pop; 3623 binOps = binOps.pop;
3895 } 3624 }
3896 3625
3897 /* 3626 // Handle conditional expression as a special form:
3898 * Handle conditional expression as a special form: 3627 // <condexp> ? <trueexp> : <falseexp>
3899 * <condexp> ? <trueexp> : <falseexp>
3900 */
3901 if(binOp.token is TokenKwQMark) 3628 if(binOp.token is TokenKwQMark)
3902 { 3629 {
3903 TokenRValCondExpr condExpr = new TokenRValCondExpr(binOp.token); 3630 TokenRValCondExpr condExpr = new TokenRValCondExpr(binOp.token);
@@ -3910,15 +3637,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3910 goto done; 3637 goto done;
3911 } 3638 }
3912 3639
3913 /* 3640 // Push new operator on its stack.
3914 * Push new operator on its stack.
3915 */
3916 binOp.pop = binOps; 3641 binOp.pop = binOps;
3917 binOps = binOp; 3642 binOps = binOp;
3918 3643
3919 /* 3644 // Push next operand on its stack.
3920 * Push next operand on its stack.
3921 */
3922 TokenRVal operand = GetOperand(ref token); 3645 TokenRVal operand = GetOperand(ref token);
3923 if(operand == null) 3646 if(operand == null)
3924 return null; 3647 return null;
@@ -3927,9 +3650,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3927 } 3650 }
3928 done: 3651 done:
3929 3652
3930 /* 3653 // At end of expression, perform any stacked computations.
3931 * At end of expression, perform any stacked computations.
3932 */
3933 while(binOps != null) 3654 while(binOps != null)
3934 { 3655 {
3935 TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands); 3656 TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands);
@@ -3938,15 +3659,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3938 binOps = binOps.pop; 3659 binOps = binOps.pop;
3939 } 3660 }
3940 3661
3941 /* 3662 // There should be exactly one remaining operand on the stack which is our final result.
3942 * There should be exactly one remaining operand on the stack which is our final result.
3943 */
3944 if(operands.prevToken != null) 3663 if(operands.prevToken != null)
3945 throw new Exception("too many operands"); 3664 throw new Exception("too many operands");
3946 3665
3947 /* 3666 // If only one terminator type possible, advance past the terminator.
3948 * If only one terminator type possible, advance past the terminator.
3949 */
3950 if(termTokenTypes.Length == 1) 3667 if(termTokenTypes.Length == 1)
3951 token = token.nextToken; 3668 token = token.nextToken;
3952 3669
@@ -4028,9 +3745,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4028 */ 3745 */
4029 private TokenRVal GetOperand(ref Token token) 3746 private TokenRVal GetOperand(ref Token token)
4030 { 3747 {
4031 /* 3748 // Prefix unary operators (eg ++, --) requiring an L-value.
4032 * Prefix unary operators (eg ++, --) requiring an L-value.
4033 */
4034 if((token is TokenKwIncr) || (token is TokenKwDecr)) 3749 if((token is TokenKwIncr) || (token is TokenKwDecr))
4035 { 3750 {
4036 TokenRValAsnPre asnPre = new TokenRValAsnPre(token); 3751 TokenRValAsnPre asnPre = new TokenRValAsnPre(token);
@@ -4048,17 +3763,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4048 return asnPre; 3763 return asnPre;
4049 } 3764 }
4050 3765
4051 /* 3766 // Get the bulk of the operand, ie, without any of the below suffixes.
4052 * Get the bulk of the operand, ie, without any of the below suffixes.
4053 */
4054 TokenRVal operand = GetOperandNoMods(ref token); 3767 TokenRVal operand = GetOperandNoMods(ref token);
4055 if(operand == null) 3768 if(operand == null)
4056 return null; 3769 return null;
4057 modifiers: 3770 modifiers:
4058 3771
4059 /* 3772 // If followed by '++' or '--', it is post-{in,de}cremented.
4060 * If followed by '++' or '--', it is post-{in,de}cremented.
4061 */
4062 if((token is TokenKwIncr) || (token is TokenKwDecr)) 3773 if((token is TokenKwIncr) || (token is TokenKwDecr))
4063 { 3774 {
4064 TokenRValAsnPost asnPost = new TokenRValAsnPost(token); 3775 TokenRValAsnPost asnPost = new TokenRValAsnPost(token);
@@ -4073,9 +3784,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4073 return asnPost; 3784 return asnPost;
4074 } 3785 }
4075 3786
4076 /* 3787 // If followed by a '.', it is an instance field or instance method reference.
4077 * If followed by a '.', it is an instance field or instance method reference.
4078 */
4079 if(token is TokenKwDot) 3788 if(token is TokenKwDot)
4080 { 3789 {
4081 token = token.nextToken; 3790 token = token.nextToken;
@@ -4092,17 +3801,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4092 goto modifiers; 3801 goto modifiers;
4093 } 3802 }
4094 3803
4095 /* 3804 // If followed by a '[', it is an array subscript.
4096 * If followed by a '[', it is an array subscript.
4097 */
4098 if(token is TokenKwBrkOpen) 3805 if(token is TokenKwBrkOpen)
4099 { 3806 {
4100 TokenLValArEle tokenLValArEle = new TokenLValArEle(token); 3807 TokenLValArEle tokenLValArEle = new TokenLValArEle(token);
4101 token = token.nextToken; 3808 token = token.nextToken;
4102 3809
4103 /* 3810 // Parse subscript(s) expression.
4104 * Parse subscript(s) expression.
4105 */
4106 tokenLValArEle.subRVal = ParseRVal(ref token, brkCloseOnly); 3811 tokenLValArEle.subRVal = ParseRVal(ref token, brkCloseOnly);
4107 if(tokenLValArEle.subRVal == null) 3812 if(tokenLValArEle.subRVal == null)
4108 { 3813 {
@@ -4110,44 +3815,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4110 return null; 3815 return null;
4111 } 3816 }
4112 3817
4113 /* 3818 // See if comma-separated list of values.
4114 * See if comma-separated list of values.
4115 */
4116 TokenRVal subscriptRVals; 3819 TokenRVal subscriptRVals;
4117 int numSubscripts = SplitCommaRVals(tokenLValArEle.subRVal, out subscriptRVals); 3820 int numSubscripts = SplitCommaRVals(tokenLValArEle.subRVal, out subscriptRVals);
4118 if(numSubscripts > 1) 3821 if(numSubscripts > 1)
4119 { 3822 {
4120 3823 // If so, put the values in an LSL_List object.
4121 /*
4122 * If so, put the values in an LSL_List object.
4123 */
4124 TokenRValList rValList = new TokenRValList(tokenLValArEle); 3824 TokenRValList rValList = new TokenRValList(tokenLValArEle);
4125 rValList.rVal = subscriptRVals; 3825 rValList.rVal = subscriptRVals;
4126 rValList.nItems = numSubscripts; 3826 rValList.nItems = numSubscripts;
4127 tokenLValArEle.subRVal = rValList; 3827 tokenLValArEle.subRVal = rValList;
4128 } 3828 }
4129 3829
4130 /* 3830 // Either way, save array variable name
4131 * Either way, save array variable name 3831 // and substitute whole reference for L-value
4132 * and substitute whole reference for L-value
4133 */
4134 tokenLValArEle.baseRVal = operand; 3832 tokenLValArEle.baseRVal = operand;
4135 operand = tokenLValArEle; 3833 operand = tokenLValArEle;
4136 goto modifiers; 3834 goto modifiers;
4137 } 3835 }
4138 3836
4139 /* 3837 // If followed by a '(', it is a function/method call.
4140 * If followed by a '(', it is a function/method call.
4141 */
4142 if(token is TokenKwParOpen) 3838 if(token is TokenKwParOpen)
4143 { 3839 {
4144 operand = ParseRValCall(ref token, operand); 3840 operand = ParseRValCall(ref token, operand);
4145 goto modifiers; 3841 goto modifiers;
4146 } 3842 }
4147 3843
4148 /* 3844 // If 'new' arraytipe '{', it is an array initializer.
4149 * If 'new' arraytipe '{', it is an array initializer.
4150 */
4151 if((token is TokenKwBrcOpen) && (operand is TokenLValSField) && 3845 if((token is TokenKwBrcOpen) && (operand is TokenLValSField) &&
4152 (((TokenLValSField)operand).fieldName.val == "$new") && 3846 (((TokenLValSField)operand).fieldName.val == "$new") &&
4153 ((TokenLValSField)operand).baseType.ToString().EndsWith("]")) 3847 ((TokenLValSField)operand).baseType.ToString().EndsWith("]"))
@@ -4165,9 +3859,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4165 */ 3859 */
4166 private TokenRVal GetOperandNoMods(ref Token token) 3860 private TokenRVal GetOperandNoMods(ref Token token)
4167 { 3861 {
4168 /* 3862 // Simple unary operators.
4169 * Simple unary operators.
4170 */
4171 if((token is TokenKwSub) || 3863 if((token is TokenKwSub) ||
4172 (token is TokenKwTilde) || 3864 (token is TokenKwTilde) ||
4173 (token is TokenKwExclam)) 3865 (token is TokenKwExclam))
@@ -4180,9 +3872,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4180 return PerformUnOp(uop, rVal); 3872 return PerformUnOp(uop, rVal);
4181 } 3873 }
4182 3874
4183 /* 3875 // Type casting.
4184 * Type casting.
4185 */
4186 if((token is TokenKwParOpen) && 3876 if((token is TokenKwParOpen) &&
4187 (token.nextToken is TokenType) && 3877 (token.nextToken is TokenType) &&
4188 (token.nextToken.nextToken is TokenKwParClose)) 3878 (token.nextToken.nextToken is TokenKwParClose))
@@ -4195,17 +3885,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4195 return new TokenRValCast(type, rVal); 3885 return new TokenRValCast(type, rVal);
4196 } 3886 }
4197 3887
4198 /* 3888 // Parenthesized expression.
4199 * Parenthesized expression.
4200 */
4201 if(token is TokenKwParOpen) 3889 if(token is TokenKwParOpen)
4202 { 3890 {
4203 return ParseRValParen(ref token); 3891 return ParseRValParen(ref token);
4204 } 3892 }
4205 3893
4206 /* 3894 // Constants.
4207 * Constants.
4208 */
4209 if(token is TokenChar) 3895 if(token is TokenChar)
4210 { 3896 {
4211 TokenRValConst rValConst = new TokenRValConst(token, ((TokenChar)token).val); 3897 TokenRValConst rValConst = new TokenRValConst(token, ((TokenChar)token).val);
@@ -4237,9 +3923,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4237 return rValUndef; 3923 return rValUndef;
4238 } 3924 }
4239 3925
4240 /* 3926 // '<'value,...'>', ie, rotation or vector
4241 * '<'value,...'>', ie, rotation or vector
4242 */
4243 if(token is TokenKwCmpLT) 3927 if(token is TokenKwCmpLT)
4244 { 3928 {
4245 Token openBkt = token; 3929 Token openBkt = token;
@@ -4277,9 +3961,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4277 } 3961 }
4278 } 3962 }
4279 3963
4280 /* 3964 // '['value,...']', ie, list
4281 * '['value,...']', ie, list
4282 */
4283 if(token is TokenKwBrkOpen) 3965 if(token is TokenKwBrkOpen)
4284 { 3966 {
4285 TokenRValList rValList = new TokenRValList(token); 3967 TokenRValList rValList = new TokenRValList(token);
@@ -4298,9 +3980,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4298 return rValList; 3980 return rValList;
4299 } 3981 }
4300 3982
4301 /* 3983 // Maybe we have <type>.<name> referencing a static field or method of some type.
4302 * Maybe we have <type>.<name> referencing a static field or method of some type.
4303 */
4304 if((token is TokenType) && (token.nextToken is TokenKwDot) && (token.nextToken.nextToken is TokenName)) 3984 if((token is TokenType) && (token.nextToken is TokenKwDot) && (token.nextToken.nextToken is TokenName))
4305 { 3985 {
4306 TokenLValSField field = new TokenLValSField(token.nextToken.nextToken); 3986 TokenLValSField field = new TokenLValSField(token.nextToken.nextToken);
@@ -4310,9 +3990,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4310 return field; 3990 return field;
4311 } 3991 }
4312 3992
4313 /* 3993 // Maybe we have 'this' referring to the object of the instance method.
4314 * Maybe we have 'this' referring to the object of the instance method.
4315 */
4316 if(token is TokenKwThis) 3994 if(token is TokenKwThis)
4317 { 3995 {
4318 if((currentDeclSDType == null) || !(currentDeclSDType is TokenDeclSDTypeClass)) 3996 if((currentDeclSDType == null) || !(currentDeclSDType is TokenDeclSDTypeClass))
@@ -4326,9 +4004,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4326 return zhis; 4004 return zhis;
4327 } 4005 }
4328 4006
4329 /* 4007 // Maybe we have 'base' referring to a field/method of the extended class.
4330 * Maybe we have 'base' referring to a field/method of the extended class.
4331 */
4332 if(token is TokenKwBase) 4008 if(token is TokenKwBase)
4333 { 4009 {
4334 if((currentDeclFunc == null) || (currentDeclFunc.sdtClass == null) || !(currentDeclFunc.sdtClass is TokenDeclSDTypeClass)) 4010 if((currentDeclFunc == null) || (currentDeclFunc.sdtClass == null) || !(currentDeclFunc.sdtClass is TokenDeclSDTypeClass))
@@ -4351,11 +4027,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4351 return baseField; 4027 return baseField;
4352 } 4028 }
4353 4029
4354 /* 4030 // Maybe we have 'new <script-defined-type>' saying to create an object instance.
4355 * Maybe we have 'new <script-defined-type>' saying to create an object instance. 4031 // This ends up generating a call to static function <script-defined-type>.$new(...)
4356 * This ends up generating a call to static function <script-defined-type>.$new(...) 4032 // whose CIL code is generated by GenerateNewobjBody().
4357 * whose CIL code is generated by GenerateNewobjBody().
4358 */
4359 if(token is TokenKwNew) 4033 if(token is TokenKwNew)
4360 { 4034 {
4361 if(!(token.nextToken is TokenType)) 4035 if(!(token.nextToken is TokenType))
@@ -4371,9 +4045,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4371 return field; 4045 return field;
4372 } 4046 }
4373 4047
4374 /* 4048 // All we got left is <name>, eg, arg, function, global or local variable reference
4375 * All we got left is <name>, eg, arg, function, global or local variable reference
4376 */
4377 if(token is TokenName) 4049 if(token is TokenName)
4378 { 4050 {
4379 TokenLValName name = new TokenLValName((TokenName)token, tokenScript.variablesStack); 4051 TokenLValName name = new TokenLValName((TokenName)token, tokenScript.variablesStack);
@@ -4381,9 +4053,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4381 return name; 4053 return name;
4382 } 4054 }
4383 4055
4384 /* 4056 // Who knows what it is supposed to be?
4385 * Who knows what it is supposed to be?
4386 */
4387 ErrorMsg(token, "invalid operand token"); 4057 ErrorMsg(token, "invalid operand token");
4388 token = SkipPastSemi(token); 4058 token = SkipPastSemi(token);
4389 return null; 4059 return null;
@@ -4398,15 +4068,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4398 */ 4068 */
4399 private TokenRValCall ParseRValCall(ref Token token, TokenRVal meth) 4069 private TokenRValCall ParseRValCall(ref Token token, TokenRVal meth)
4400 { 4070 {
4401 /* 4071 // Set up basic function call struct with function name.
4402 * Set up basic function call struct with function name.
4403 */
4404 TokenRValCall rValCall = new TokenRValCall(token); 4072 TokenRValCall rValCall = new TokenRValCall(token);
4405 rValCall.meth = meth; 4073 rValCall.meth = meth;
4406 4074
4407 /* 4075 // Parse the call parameters, if any.
4408 * Parse the call parameters, if any.
4409 */
4410 token = token.nextToken; 4076 token = token.nextToken;
4411 if(token is TokenKwParClose) 4077 if(token is TokenKwParClose)
4412 { 4078 {
@@ -4747,24 +4413,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4747 */ 4413 */
4748 public TokenDeclSDType InstantiateGeneric(string name, TokenType[] genArgs, ScriptReduce reduce) 4414 public TokenDeclSDType InstantiateGeneric(string name, TokenType[] genArgs, ScriptReduce reduce)
4749 { 4415 {
4750 /* 4416 // Malloc the struct and give it a name.
4751 * Malloc the struct and give it a name.
4752 */
4753 TokenDeclSDType instdecl = this.MakeBlank(new TokenName(this, name)); 4417 TokenDeclSDType instdecl = this.MakeBlank(new TokenName(this, name));
4754 4418
4755 /* 4419 // If the original had an outer type, then so does the new one.
4756 * If the original had an outer type, then so does the new one. 4420 // The outer type will never be a generic prototype, eg, if this
4757 * The outer type will never be a generic prototype, eg, if this 4421 // is 'ValueList' it will always be inside 'Dictionary<string,integer>'
4758 * is 'ValueList' it will always be inside 'Dictionary<string,integer>' 4422 // not 'Dictionary' at this point.
4759 * not 'Dictionary' at this point.
4760 */
4761 if((this.outerSDType != null) && (this.outerSDType.genParams != null)) 4423 if((this.outerSDType != null) && (this.outerSDType.genParams != null))
4762 throw new Exception(); 4424 throw new Exception();
4763 instdecl.outerSDType = this.outerSDType; 4425 instdecl.outerSDType = this.outerSDType;
4764 4426
4765 /* 4427 // The generic prototype may have stuff like 'public' just before it and we need to copy that too.
4766 * The generic prototype may have stuff like 'public' just before it and we need to copy that too.
4767 */
4768 Token prefix; 4428 Token prefix;
4769 for(prefix = this; (prefix = prefix.prevToken) != null;) 4429 for(prefix = this; (prefix = prefix.prevToken) != null;)
4770 { 4430 {
@@ -4773,108 +4433,78 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4773 } 4433 }
4774 this.begToken = prefix.nextToken; 4434 this.begToken = prefix.nextToken;
4775 4435
4776 /* 4436 // Splice in a copy of the prefix tokens, just before the beginning token of prototype (this.begToken).
4777 * Splice in a copy of the prefix tokens, just before the beginning token of prototype (this.begToken).
4778 */
4779 while((prefix = prefix.nextToken) != this) 4437 while((prefix = prefix.nextToken) != this)
4780 { 4438 {
4781 SpliceSourceToken(prefix.CopyToken(prefix)); 4439 SpliceSourceToken(prefix.CopyToken(prefix));
4782 } 4440 }
4783 4441
4784 /* 4442 // Splice instantiation (instdecl) in just before the beginning token of prototype (this.begToken).
4785 * Splice instantiation (instdecl) in just before the beginning token of prototype (this.begToken).
4786 */
4787 SpliceSourceToken(instdecl); 4443 SpliceSourceToken(instdecl);
4788 4444
4789 /* 4445 // Now for the fun part... Copy the rest of the prototype body to the
4790 * Now for the fun part... Copy the rest of the prototype body to the 4446 // instantiated body, replacing all generic parameter type tokens with
4791 * instantiated body, replacing all generic parameter type tokens with 4447 // the corresponding generic argument types. Note that the parameters
4792 * the corresponding generic argument types. Note that the parameters 4448 // are numbered starting with the outermost so we need the full genArgs
4793 * are numbered starting with the outermost so we need the full genArgs 4449 // array. Eg if we are doing 'Converter<V=float>' from
4794 * array. Eg if we are doing 'Converter<V=float>' from 4450 // 'Dictionary<T=string,U=integer>.Converter<V=float>', any V's are
4795 * 'Dictionary<T=string,U=integer>.Converter<V=float>', any V's are 4451 // numbered [2]. Any [0]s or [1]s should be gone by now but it doesn't
4796 * numbered [2]. Any [0]s or [1]s should be gone by now but it doesn't 4452 // matter.
4797 * matter.
4798 */
4799 int index; 4453 int index;
4800 Token it, pt; 4454 Token it, pt;
4801 TokenDeclSDType innerProto = this; 4455 TokenDeclSDType innerProto = this;
4802 TokenDeclSDType innerInst = instdecl; 4456 TokenDeclSDType innerInst = instdecl;
4803 for(pt = this; (pt = pt.nextToken) != this.endToken;) 4457 for(pt = this; (pt = pt.nextToken) != this.endToken;)
4804 { 4458 {
4805 4459 // Coming across a sub-type's declaration involves a deep copy of the
4806 /* 4460 // declaration token. Fortunately we are early on in parsing, so there
4807 * Coming across a sub-type's declaration involves a deep copy of the 4461 // really isn't much to copy:
4808 * declaration token. Fortunately we are early on in parsing, so there 4462 // 1) short name is the same, eg, doing List of Dictionary<string,integer>.List is same short name as Dictionary<T,U>.List
4809 * really isn't much to copy: 4463 // if generic, eg doing Converter<W> of Dictionary<T,U>.Converter<W>, we have to manually copy the W as well.
4810 * 1) short name is the same, eg, doing List of Dictionary<string,integer>.List is same short name as Dictionary<T,U>.List 4464 // 2) outerSDType is transformed from Dictionary<T,U> to Dictionary<string,integer>.
4811 * if generic, eg doing Converter<W> of Dictionary<T,U>.Converter<W>, we have to manually copy the W as well. 4465 // 3) innerSDTypes is rebuilt when/if we find classes that are inner to this one.
4812 * 2) outerSDType is transformed from Dictionary<T,U> to Dictionary<string,integer>.
4813 * 3) innerSDTypes is rebuilt when/if we find classes that are inner to this one.
4814 */
4815 if(pt is TokenDeclSDType) 4466 if(pt is TokenDeclSDType)
4816 { 4467 {
4817 4468 // Make a new TokenDeclSDType{Class,Delegate,Interface}.
4818 /*
4819 * Make a new TokenDeclSDType{Class,Delegate,Interface}.
4820 */
4821 TokenDeclSDType ptSDType = (TokenDeclSDType)pt; 4469 TokenDeclSDType ptSDType = (TokenDeclSDType)pt;
4822 TokenDeclSDType itSDType = ptSDType.MakeBlank(new TokenName(ptSDType.shortName, ptSDType.shortName.val)); 4470 TokenDeclSDType itSDType = ptSDType.MakeBlank(new TokenName(ptSDType.shortName, ptSDType.shortName.val));
4823 4471
4824 /* 4472 // Set up the transformed outerSDType.
4825 * Set up the transformed outerSDType. 4473 // Eg, if we are creating Enumerator of Dictionary<string,integer>.Enumerator,
4826 * Eg, if we are creating Enumerator of Dictionary<string,integer>.Enumerator, 4474 // innerProto = Dictionary<T,U> and innerInst = Dictionary<string,integer>.
4827 * innerProto = Dictionary<T,U> and innerInst = Dictionary<string,integer>.
4828 */
4829 itSDType.outerSDType = innerInst; 4475 itSDType.outerSDType = innerInst;
4830 4476
4831 /* 4477 // This clone is an inner type of its next outer level.
4832 * This clone is an inner type of its next outer level.
4833 */
4834 reduce.CatalogSDTypeDecl(itSDType); 4478 reduce.CatalogSDTypeDecl(itSDType);
4835 4479
4836 /* 4480 // We need to manually copy any generic parameters of the class declaration being cloned.
4837 * We need to manually copy any generic parameters of the class declaration being cloned. 4481 // eg, if we are cloning Converter<W>, this is where the W gets copied.
4838 * eg, if we are cloning Converter<W>, this is where the W gets copied. 4482 // Since it is an immutable array of strings, just copy the array pointer, if any.
4839 * Since it is an immutable array of strings, just copy the array pointer, if any.
4840 */
4841 itSDType.genParams = ptSDType.genParams; 4483 itSDType.genParams = ptSDType.genParams;
4842 4484
4843 /* 4485 // We are now processing tokens for this cloned type declaration.
4844 * We are now processing tokens for this cloned type declaration.
4845 */
4846 innerProto = ptSDType; 4486 innerProto = ptSDType;
4847 innerInst = itSDType; 4487 innerInst = itSDType;
4848 4488
4849 /* 4489 // Splice this clone token in.
4850 * Splice this clone token in.
4851 */
4852 it = itSDType; 4490 it = itSDType;
4853 } 4491 }
4854 4492
4855 /* 4493 // Check for an generic parameter to substitute out.
4856 * Check for an generic parameter to substitute out.
4857 */
4858 else if((pt is TokenName) && this.genParams.TryGetValue(((TokenName)pt).val, out index)) 4494 else if((pt is TokenName) && this.genParams.TryGetValue(((TokenName)pt).val, out index))
4859 { 4495 {
4860 it = genArgs[index].CopyToken(pt); 4496 it = genArgs[index].CopyToken(pt);
4861 } 4497 }
4862 4498
4863 /* 4499 // Everything else is a simple copy.
4864 * Everything else is a simple copy.
4865 */
4866 else 4500 else
4867 it = pt.CopyToken(pt); 4501 it = pt.CopyToken(pt);
4868 4502
4869 /* 4503 // Whatever we came up with, splice it into the source token stream.
4870 * Whatever we came up with, splice it into the source token stream.
4871 */
4872 SpliceSourceToken(it); 4504 SpliceSourceToken(it);
4873 4505
4874 /* 4506 // Maybe we just finished copying an inner type definition.
4875 * Maybe we just finished copying an inner type definition. 4507 // If so, remember where it ends and pop it from the stack.
4876 * If so, remember where it ends and pop it from the stack.
4877 */
4878 if(innerProto.endToken == pt) 4508 if(innerProto.endToken == pt)
4879 { 4509 {
4880 innerInst.endToken = it; 4510 innerInst.endToken = it;
@@ -4883,9 +4513,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
4883 } 4513 }
4884 } 4514 }
4885 4515
4886 /* 4516 // Clone and insert the terminator, either '}' or ';'
4887 * Clone and insert the terminator, either '}' or ';'
4888 */
4889 it = pt.CopyToken(pt); 4517 it = pt.CopyToken(pt);
4890 SpliceSourceToken(it); 4518 SpliceSourceToken(it);
4891 instdecl.endToken = it; 4519 instdecl.endToken = it;
@@ -5225,16 +4853,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5225 4853
5226 if((numVirtFuncs > 0) && (stackedMethods != null)) 4854 if((numVirtFuncs > 0) && (stackedMethods != null))
5227 { 4855 {
5228 4856 // Allocate arrays big enough for mine plus type we are extending.
5229 /*
5230 * Allocate arrays big enough for mine plus type we are extending.
5231 */
5232 vDynMeths = new DynamicMethod[numVirtFuncs]; 4857 vDynMeths = new DynamicMethod[numVirtFuncs];
5233 vMethTypes = new Type[numVirtFuncs]; 4858 vMethTypes = new Type[numVirtFuncs];
5234 4859
5235 /* 4860 // Fill in low parts from type we are extending.
5236 * Fill in low parts from type we are extending.
5237 */
5238 if(extends != null) 4861 if(extends != null)
5239 { 4862 {
5240 int n = extends.numVirtFuncs; 4863 int n = extends.numVirtFuncs;
@@ -5245,10 +4868,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5245 } 4868 }
5246 } 4869 }
5247 4870
5248 /* 4871 // Fill in high parts with my own methods.
5249 * Fill in high parts with my own methods. 4872 // Might also overwrite lower ones with 'override' methods.
5250 * Might also overwrite lower ones with 'override' methods.
5251 */
5252 foreach(StackedMethod sm in stackedMethods) 4873 foreach(StackedMethod sm in stackedMethods)
5253 { 4874 {
5254 int i = sm.methVTI; 4875 int i = sm.methVTI;
@@ -5294,16 +4915,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5294 4915
5295 public override void DebString(StringBuilder sb) 4916 public override void DebString(StringBuilder sb)
5296 { 4917 {
5297 /* 4918 // Don't output if array of some type.
5298 * Don't output if array of some type. 4919 // They will be re-instantiated as referenced by rest of script.
5299 * They will be re-instantiated as referenced by rest of script.
5300 */
5301 if(arrayOfType != null) 4920 if(arrayOfType != null)
5302 return; 4921 return;
5303 4922
5304 /* 4923 // This class name and extended/implemented type declaration.
5305 * This class name and extended/implemented type declaration.
5306 */
5307 sb.Append("class "); 4924 sb.Append("class ");
5308 sb.Append(shortName.val); 4925 sb.Append(shortName.val);
5309 bool first = true; 4926 bool first = true;
@@ -5321,17 +4938,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5321 } 4938 }
5322 sb.Append(" {"); 4939 sb.Append(" {");
5323 4940
5324 /* 4941 // Inner type definitions.
5325 * Inner type definitions.
5326 */
5327 foreach(TokenDeclSDType subs in innerSDTypes.Values) 4942 foreach(TokenDeclSDType subs in innerSDTypes.Values)
5328 { 4943 {
5329 subs.DebString(sb); 4944 subs.DebString(sb);
5330 } 4945 }
5331 4946
5332 /* 4947 // Members (fields, methods, properties).
5333 * Members (fields, methods, properties).
5334 */
5335 foreach(TokenDeclVar memb in members) 4948 foreach(TokenDeclVar memb in members)
5336 { 4949 {
5337 if((memb == instFieldInit) || (memb == staticFieldInit)) 4950 if((memb == instFieldInit) || (memb == staticFieldInit))
@@ -5511,12 +5124,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5511 { 5124 {
5512 int nArgs; 5125 int nArgs;
5513 5126
5514 /* 5127 // This happens when the node was restored via ReadFromFile().
5515 * This happens when the node was restored via ReadFromFile(). 5128 // It leaves the types in retStr/argStrs for resolution after
5516 * It leaves the types in retStr/argStrs for resolution after 5129 // all definitions have been read from the object file in case
5517 * all definitions have been read from the object file in case 5130 // there are forward references.
5518 * there are forward references.
5519 */
5520 if(retType == null) 5131 if(retType == null)
5521 { 5132 {
5522 retType = MakeTypeToken(retStr); 5133 retType = MakeTypeToken(retStr);
@@ -5531,10 +5142,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5531 } 5142 }
5532 } 5143 }
5533 5144
5534 /* 5145 // Fill in system types from token types.
5535 * Fill in system types from token types. 5146 // Might as well build the signature strings too from token types.
5536 * Might as well build the signature strings too from token types.
5537 */
5538 retSysType = retType.ToSysType(); 5147 retSysType = retType.ToSysType();
5539 5148
5540 nArgs = argTypes.Length; 5149 nArgs = argTypes.Length;
@@ -5552,11 +5161,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5552 argSig = sb.ToString(); 5161 argSig = sb.ToString();
5553 wholeSig = retType.ToString() + argSig; 5162 wholeSig = retType.ToString() + argSig;
5554 5163
5555 /* 5164 // Now we can create a system delegate type from the given
5556 * Now we can create a system delegate type from the given 5165 // return and argument types. Give it an unique name using
5557 * return and argument types. Give it an unique name using 5166 // the whole signature string.
5558 * the whole signature string.
5559 */
5560 sysType = DelegateCommon.GetType(retSysType, argSysTypes, wholeSig); 5167 sysType = DelegateCommon.GetType(retSysType, argSysTypes, wholeSig);
5561 } 5168 }
5562 5169
@@ -5570,9 +5177,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5570 { 5177 {
5571 TokenDeclSDTypeDelegate decldel; 5178 TokenDeclSDTypeDelegate decldel;
5572 5179
5573 /* 5180 // Name it after the whole signature string.
5574 * Name it after the whole signature string.
5575 */
5576 StringBuilder sb = new StringBuilder("$inline"); 5181 StringBuilder sb = new StringBuilder("$inline");
5577 sb.Append(retType.ToString()); 5182 sb.Append(retType.ToString());
5578 sb.Append("("); 5183 sb.Append("(");
@@ -5588,10 +5193,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5588 string inlname = sb.ToString(); 5193 string inlname = sb.ToString();
5589 if(!inlines.TryGetValue(inlname, out decldel)) 5194 if(!inlines.TryGetValue(inlname, out decldel))
5590 { 5195 {
5591 5196 // Create the corresponding declaration and link to it
5592 /*
5593 * Create the corresponding declaration and link to it
5594 */
5595 TokenName name = new TokenName(null, inlname); 5197 TokenName name = new TokenName(null, inlname);
5596 decldel = new TokenDeclSDTypeDelegate(name); 5198 decldel = new TokenDeclSDTypeDelegate(name);
5597 decldel.retType = retType; 5199 decldel.retType = retType;
@@ -5860,9 +5462,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5860 { 5462 {
5861 TokenDeclSDTypeDelegate decldel; 5463 TokenDeclSDTypeDelegate decldel;
5862 5464
5863 /* 5465 // See if we already have a matching declared one cataloged.
5864 * See if we already have a matching declared one cataloged.
5865 */
5866 int nArgs = argTypes.Length; 5466 int nArgs = argTypes.Length;
5867 foreach(TokenDeclSDType decl in tokenScript.sdSrcTypesValues) 5467 foreach(TokenDeclSDType decl in tokenScript.sdSrcTypesValues)
5868 { 5468 {
@@ -5886,9 +5486,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
5886 ; 5486 ;
5887 } 5487 }
5888 5488
5889 /* 5489 // No such luck, create a new anonymous declaration.
5890 * No such luck, create a new anonymous declaration.
5891 */
5892 StringBuilder sb = new StringBuilder("$anondel$"); 5490 StringBuilder sb = new StringBuilder("$anondel$");
5893 sb.Append(retType.ToString()); 5491 sb.Append(retType.ToString());
5894 sb.Append("("); 5492 sb.Append("(");
@@ -6309,50 +5907,36 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6309 */ 5907 */
6310 public bool IsFuncTrivial(ScriptCodeGen scg) 5908 public bool IsFuncTrivial(ScriptCodeGen scg)
6311 { 5909 {
6312 /* 5910 // If not really a function, assume it's a delegate.
6313 * If not really a function, assume it's a delegate. 5911 // And since we don't really know what functions it can point to,
6314 * And since we don't really know what functions it can point to, 5912 // assume it can point to a non-trivial one.
6315 * assume it can point to a non-trivial one.
6316 */
6317 if(retType == null) 5913 if(retType == null)
6318 return false; 5914 return false;
6319 5915
6320 /* 5916 // All virtual functions are non-trivial because although a particular
6321 * All virtual functions are non-trivial because although a particular 5917 // one might be trivial, it might be overidden with a non-trivial one.
6322 * one might be trivial, it might be overidden with a non-trivial one.
6323 */
6324 if((sdtFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE | 5918 if((sdtFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE |
6325 ScriptReduce.SDT_VIRTUAL)) != 0) 5919 ScriptReduce.SDT_VIRTUAL)) != 0)
6326 { 5920 {
6327 return false; 5921 return false;
6328 } 5922 }
6329 5923
6330 /* 5924 // Check the triviality status of the function.
6331 * Check the triviality status of the function.
6332 */
6333 switch(triviality) 5925 switch(triviality)
6334 { 5926 {
6335 5927 // Don't yet know if it is trivial.
6336 /* 5928 // We know at this point it doesn't have any direct looping.
6337 * Don't yet know if it is trivial. 5929 // But if it calls something that has loops, it isn't trivial.
6338 * We know at this point it doesn't have any direct looping. 5930 // Otherwise it is trivial.
6339 * But if it calls something that has loops, it isn't trivial.
6340 * Otherwise it is trivial.
6341 */
6342 case Triviality.unknown: 5931 case Triviality.unknown:
6343 { 5932 {
6344 5933 // Mark that we are analyzing this function now. So if there are
6345 /* 5934 // any recursive call loops, that will show that the function is
6346 * Mark that we are analyzing this function now. So if there are 5935 // non-trivial and the analysis will terminate at that point.
6347 * any recursive call loops, that will show that the function is
6348 * non-trivial and the analysis will terminate at that point.
6349 */
6350 triviality = Triviality.analyzing; 5936 triviality = Triviality.analyzing;
6351 5937
6352 /* 5938 // Check out everything else this function calls. If any say they
6353 * Check out everything else this function calls. If any say they 5939 // aren't trivial, then we say this function isn't trivial.
6354 * aren't trivial, then we say this function isn't trivial.
6355 */
6356 foreach(TokenRValCall call in unknownTrivialityCalls) 5940 foreach(TokenRValCall call in unknownTrivialityCalls)
6357 { 5941 {
6358 if(!call.IsRValTrivial(scg, null)) 5942 if(!call.IsRValTrivial(scg, null))
@@ -6362,28 +5946,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6362 } 5946 }
6363 } 5947 }
6364 5948
6365 /* 5949 // All functions called by this function are trivial, and this
6366 * All functions called by this function are trivial, and this 5950 // function's code doesn't have any loops, so we can mark this
6367 * function's code doesn't have any loops, so we can mark this 5951 // function as being trivial.
6368 * function as being trivial.
6369 */
6370 triviality = Triviality.trivial; 5952 triviality = Triviality.trivial;
6371 return true; 5953 return true;
6372 } 5954 }
6373 5955
6374 /* 5956 // We already know that it is trivial.
6375 * We already know that it is trivial.
6376 */
6377 case Triviality.trivial: 5957 case Triviality.trivial:
6378 { 5958 {
6379 return true; 5959 return true;
6380 } 5960 }
6381 5961
6382 /* 5962 // We either know it is complex or are trying to analyze it already.
6383 * We either know it is complex or are trying to analyze it already. 5963 // If we are already analyzing it, it means it has a recursive loop
6384 * If we are already analyzing it, it means it has a recursive loop 5964 // and we assume those are non-trivial.
6385 * and we assume those are non-trivial.
6386 */
6387 default: 5965 default:
6388 return false; 5966 return false;
6389 } 5967 }
@@ -6450,22 +6028,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6450 6028
6451 for(Token stmt = body.statements; stmt != null; stmt = stmt.nextToken) 6029 for(Token stmt = body.statements; stmt != null; stmt = stmt.nextToken)
6452 { 6030 {
6453 6031 // Body of the function should all be arithmetic statements (not eg for loops, if statements etc).
6454 /*
6455 * Body of the function should all be arithmetic statements (not eg for loops, if statements etc).
6456 */
6457 TokenRVal rval = ((TokenStmtRVal)stmt).rVal; 6032 TokenRVal rval = ((TokenStmtRVal)stmt).rVal;
6458 6033
6459 /* 6034 // And the opcode should be a simple assignment operator.
6460 * And the opcode should be a simple assignment operator.
6461 */
6462 TokenRValOpBin rvob = (TokenRValOpBin)rval; 6035 TokenRValOpBin rvob = (TokenRValOpBin)rval;
6463 if(!(rvob.opcode is TokenKwAssign)) 6036 if(!(rvob.opcode is TokenKwAssign))
6464 throw new Exception("bad op type " + rvob.opcode.GetType().Name); 6037 throw new Exception("bad op type " + rvob.opcode.GetType().Name);
6465 6038
6466 /* 6039 // Get field or variable being assigned to.
6467 * Get field or variable being assigned to.
6468 */
6469 TokenDeclVar var = null; 6040 TokenDeclVar var = null;
6470 TokenRVal left = rvob.rValLeft; 6041 TokenRVal left = rvob.rValLeft;
6471 if(left is TokenLValIField) 6042 if(left is TokenLValIField)
@@ -6490,28 +6061,22 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6490 if(var == null) 6061 if(var == null)
6491 throw new Exception("unknown var type " + left.GetType().Name); 6062 throw new Exception("unknown var type " + left.GetType().Name);
6492 6063
6493 /* 6064 // Output flags, type name and bare variable name.
6494 * Output flags, type name and bare variable name. 6065 // This should look like a declaration in the 'sb'
6495 * This should look like a declaration in the 'sb' 6066 // as it is not enclosed in a function.
6496 * as it is not enclosed in a function.
6497 */
6498 var.DebStringSDTFlags(sb); 6067 var.DebStringSDTFlags(sb);
6499 var.type.DebString(sb); 6068 var.type.DebString(sb);
6500 sb.Append(' '); 6069 sb.Append(' ');
6501 sb.Append(var.name.val); 6070 sb.Append(var.name.val);
6502 6071
6503 /* 6072 // Maybe it has a non-default initialization value.
6504 * Maybe it has a non-default initialization value.
6505 */
6506 if((var.init != null) && !(var.init is TokenRValInitDef)) 6073 if((var.init != null) && !(var.init is TokenRValInitDef))
6507 { 6074 {
6508 sb.Append(" = "); 6075 sb.Append(" = ");
6509 var.init.DebString(sb); 6076 var.init.DebString(sb);
6510 } 6077 }
6511 6078
6512 /* 6079 // End of declaration statement.
6513 * End of declaration statement.
6514 */
6515 sb.Append(';'); 6080 sb.Append(';');
6516 } 6081 }
6517 } 6082 }
@@ -6578,17 +6143,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6578 { 6143 {
6579 TokenType baseType = baseRVal.GetRValType(scg, null); 6144 TokenType baseType = baseRVal.GetRValType(scg, null);
6580 6145
6581 /* 6146 // Maybe referencing element of a fixed-dimension array.
6582 * Maybe referencing element of a fixed-dimension array.
6583 */
6584 if((baseType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)baseType).decl.arrayOfType != null)) 6147 if((baseType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)baseType).decl.arrayOfType != null))
6585 { 6148 {
6586 return ((TokenTypeSDTypeClass)baseType).decl.arrayOfType; 6149 return ((TokenTypeSDTypeClass)baseType).decl.arrayOfType;
6587 } 6150 }
6588 6151
6589 /* 6152 // Maybe referencing $idxprop property of script-defined class or interface.
6590 * Maybe referencing $idxprop property of script-defined class or interface.
6591 */
6592 if(baseType is TokenTypeSDTypeClass) 6153 if(baseType is TokenTypeSDTypeClass)
6593 { 6154 {
6594 TokenDeclSDTypeClass sdtDecl = ((TokenTypeSDTypeClass)baseType).decl; 6155 TokenDeclSDTypeClass sdtDecl = ((TokenTypeSDTypeClass)baseType).decl;
@@ -6604,17 +6165,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6604 return idxProp.type; 6165 return idxProp.type;
6605 } 6166 }
6606 6167
6607 /* 6168 // Maybe referencing single character of a string.
6608 * Maybe referencing single character of a string.
6609 */
6610 if((baseType is TokenTypeKey) || (baseType is TokenTypeStr)) 6169 if((baseType is TokenTypeKey) || (baseType is TokenTypeStr))
6611 { 6170 {
6612 return new TokenTypeChar(this); 6171 return new TokenTypeChar(this);
6613 } 6172 }
6614 6173
6615 /* 6174 // Assume XMR_Array element or extracting element from list.
6616 * Assume XMR_Array element or extracting element from list.
6617 */
6618 if((baseType is TokenTypeArray) || (baseType is TokenTypeList)) 6175 if((baseType is TokenTypeArray) || (baseType is TokenTypeList))
6619 { 6176 {
6620 return new TokenTypeObject(this); 6177 return new TokenTypeObject(this);
@@ -6714,19 +6271,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6714 6271
6715 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) 6272 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig)
6716 { 6273 {
6717 /* 6274 // If getting pointer to instance isn't trivial, then accessing the member isn't trivial either.
6718 * If getting pointer to instance isn't trivial, then accessing the member isn't trivial either.
6719 */
6720 if(!baseRVal.IsRValTrivial(scg, null)) 6275 if(!baseRVal.IsRValTrivial(scg, null))
6721 return false; 6276 return false;
6722 6277
6723 /* 6278 // Accessing a member of a class depends on the member.
6724 * Accessing a member of a class depends on the member. 6279 // In the case of a method, this is accessing it as a delegate, not calling it, and
6725 * In the case of a method, this is accessing it as a delegate, not calling it, and 6280 // argsig simply serves as selecting which of possibly overloaded methods to select.
6726 * argsig simply serves as selecting which of possibly overloaded methods to select. 6281 // The case of accessing a property, however, depends on the property implementation,
6727 * The case of accessing a property, however, depends on the property implementation, 6282 // as there could be looping inside the property code.
6728 * as there could be looping inside the property code.
6729 */
6730 TokenType baseType = baseRVal.GetRValType(scg, null); 6283 TokenType baseType = baseRVal.GetRValType(scg, null);
6731 if(baseType is TokenTypeSDTypeClass) 6284 if(baseType is TokenTypeSDTypeClass)
6732 { 6285 {
@@ -6734,9 +6287,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6734 return (var != null) && var.IsVarTrivial(scg); 6287 return (var != null) && var.IsVarTrivial(scg);
6735 } 6288 }
6736 6289
6737 /* 6290 // Accessing the members of anything else (arrays, rotations, vectors) is always trivial.
6738 * Accessing the members of anything else (arrays, rotations, vectors) is always trivial.
6739 */
6740 return true; 6291 return true;
6741 } 6292 }
6742 6293
@@ -6748,15 +6299,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6748 */ 6299 */
6749 public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) 6300 public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig)
6750 { 6301 {
6751 /* 6302 // If getting pointer to instance isn't trivial, then calling the method isn't trivial either.
6752 * If getting pointer to instance isn't trivial, then calling the method isn't trivial either.
6753 */
6754 if(!baseRVal.IsRValTrivial(scg, null)) 6303 if(!baseRVal.IsRValTrivial(scg, null))
6755 return false; 6304 return false;
6756 6305
6757 /* 6306 // Calling a method of a class depends on the method.
6758 * Calling a method of a class depends on the method.
6759 */
6760 TokenType baseType = baseRVal.GetRValType(scg, null); 6307 TokenType baseType = baseRVal.GetRValType(scg, null);
6761 if(baseType is TokenTypeSDTypeClass) 6308 if(baseType is TokenTypeSDTypeClass)
6762 { 6309 {
@@ -6764,21 +6311,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6764 return (var != null) && var.IsFuncTrivial(scg); 6311 return (var != null) && var.IsFuncTrivial(scg);
6765 } 6312 }
6766 6313
6767 /* 6314 // Calling via a pointer to an interface instance is never trivial.
6768 * Calling via a pointer to an interface instance is never trivial. 6315 // (It is really a pointer to an array of delegates).
6769 * (It is really a pointer to an array of delegates). 6316 // We can't tell for this call site whether the actual method being called is trivial or not,
6770 * We can't tell for this call site whether the actual method being called is trivial or not, 6317 // so we have to assume it isn't.
6771 * so we have to assume it isn't. 6318 // ??? We could theoretically check to see if *all* implementations of this method of
6772 * ??? We could theoretically check to see if *all* implementations of this method of 6319 // this interface are trivial, then we could conclude that this call is trivial.
6773 * this interface are trivial, then we could conclude that this call is trivial.
6774 */
6775 if(baseType is TokenTypeSDTypeInterface) 6320 if(baseType is TokenTypeSDTypeInterface)
6776 return false; 6321 return false;
6777 6322
6778 /* 6323 // Calling a method of anything else (arrays, rotations, vectors) is always trivial.
6779 * Calling a method of anything else (arrays, rotations, vectors) is always trivial. 6324 // Even methods of delegates, such as ".GetArgTypes()" that we may someday do is trivial.
6780 * Even methods of delegates, such as ".GetArgTypes()" that we may someday do is trivial.
6781 */
6782 return true; 6325 return true;
6783 } 6326 }
6784 6327
@@ -6801,23 +6344,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6801 6344
6802 public TokenLValName(TokenName name, VarDict stack) : base(name) 6345 public TokenLValName(TokenName name, VarDict stack) : base(name)
6803 { 6346 {
6804 /* 6347 // Save name of variable/method/function/field.
6805 * Save name of variable/method/function/field.
6806 */
6807 this.name = name; 6348 this.name = name;
6808 6349
6809 /* 6350 // Save where in the stack it can be looked up.
6810 * Save where in the stack it can be looked up. 6351 // If the current stack is for locals, do not allow forward references.
6811 * If the current stack is for locals, do not allow forward references. 6352 // this allows idiocy like:
6812 * this allows idiocy like: 6353 // list buttons = [ 1, 2, 3 ];
6813 * list buttons = [ 1, 2, 3 ]; 6354 // x () {
6814 * x () { 6355 // list buttons = llList2List (buttons, 0, 1);
6815 * list buttons = llList2List (buttons, 0, 1); 6356 // llOwnerSay (llList2CSV (buttons));
6816 * llOwnerSay (llList2CSV (buttons)); 6357 // }
6817 * } 6358 // If it is not locals, allow forward references.
6818 * If it is not locals, allow forward references. 6359 // this allows function X() to call Y() and Y() to call X().
6819 * this allows function X() to call Y() and Y() to call X().
6820 */
6821 this.stack = stack.FreezeLocals(); 6360 this.stack = stack.FreezeLocals();
6822 } 6361 }
6823 6362
@@ -6879,22 +6418,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6879 6418
6880 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) 6419 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig)
6881 { 6420 {
6882 /* 6421 // Accessing a member of a class depends on the member.
6883 * Accessing a member of a class depends on the member. 6422 // In the case of a method, this is accessing it as a delegate, not calling it, and
6884 * In the case of a method, this is accessing it as a delegate, not calling it, and 6423 // argsig simply serves as selecting which of possibly overloaded methods to select.
6885 * argsig simply serves as selecting which of possibly overloaded methods to select. 6424 // The case of accessing a property, however, depends on the property implementation,
6886 * The case of accessing a property, however, depends on the property implementation, 6425 // as there could be looping inside the property code.
6887 * as there could be looping inside the property code.
6888 */
6889 if(baseType is TokenTypeSDTypeClass) 6426 if(baseType is TokenTypeSDTypeClass)
6890 { 6427 {
6891 TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); 6428 TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig);
6892 return (var != null) && var.IsVarTrivial(scg); 6429 return (var != null) && var.IsVarTrivial(scg);
6893 } 6430 }
6894 6431
6895 /* 6432 // Accessing the fields/methods/properties of anything else (arrays, rotations, vectors) is always trivial.
6896 * Accessing the fields/methods/properties of anything else (arrays, rotations, vectors) is always trivial.
6897 */
6898 return true; 6433 return true;
6899 } 6434 }
6900 6435
@@ -6906,18 +6441,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
6906 */ 6441 */
6907 public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) 6442 public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig)
6908 { 6443 {
6909 /* 6444 // Calling a static method of a class depends on the method.
6910 * Calling a static method of a class depends on the method.
6911 */
6912 if(baseType is TokenTypeSDTypeClass) 6445 if(baseType is TokenTypeSDTypeClass)
6913 { 6446 {
6914 TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); 6447 TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig);
6915 return (var != null) && var.IsFuncTrivial(scg); 6448 return (var != null) && var.IsFuncTrivial(scg);
6916 } 6449 }
6917 6450
6918 /* 6451 // Calling a static method of anything else (arrays, rotations, vectors) is always trivial.
6919 * Calling a static method of anything else (arrays, rotations, vectors) is always trivial.
6920 */
6921 return true; 6452 return true;
6922 } 6453 }
6923 6454
@@ -7075,9 +6606,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7075 */ 6606 */
7076 public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) 6607 public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig)
7077 { 6608 {
7078 /* 6609 // Build type signature so we select correct overloaded function.
7079 * Build type signature so we select correct overloaded function.
7080 */
7081 if(myArgSig == null) 6610 if(myArgSig == null)
7082 { 6611 {
7083 myArgSig = new TokenType[nArgs]; 6612 myArgSig = new TokenType[nArgs];
@@ -7088,9 +6617,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7088 } 6617 }
7089 } 6618 }
7090 6619
7091 /* 6620 // Get the type of the method itself. This should get us a delegate type.
7092 * Get the type of the method itself. This should get us a delegate type.
7093 */
7094 TokenType delType = meth.GetRValType(scg, myArgSig); 6621 TokenType delType = meth.GetRValType(scg, myArgSig);
7095 if(!(delType is TokenTypeSDTypeDelegate)) 6622 if(!(delType is TokenTypeSDTypeDelegate))
7096 { 6623 {
@@ -7098,9 +6625,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7098 return new TokenTypeVoid(meth); 6625 return new TokenTypeVoid(meth);
7099 } 6626 }
7100 6627
7101 /* 6628 // Get the return type from the delegate type.
7102 * Get the return type from the delegate type.
7103 */
7104 return ((TokenTypeSDTypeDelegate)delType).decl.GetRetType(); 6629 return ((TokenTypeSDTypeDelegate)delType).decl.GetRetType();
7105 } 6630 }
7106 6631
@@ -7112,9 +6637,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7112 */ 6637 */
7113 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) 6638 public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig)
7114 { 6639 {
7115 /* 6640 // Build type signature so we select correct overloaded function.
7116 * Build type signature so we select correct overloaded function.
7117 */
7118 if(myArgSig == null) 6641 if(myArgSig == null)
7119 { 6642 {
7120 myArgSig = new TokenType[nArgs]; 6643 myArgSig = new TokenType[nArgs];
@@ -7125,18 +6648,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7125 } 6648 }
7126 } 6649 }
7127 6650
7128 /* 6651 // Make sure all arguments can be computed trivially.
7129 * Make sure all arguments can be computed trivially.
7130 */
7131 for(Token t = args; t != null; t = t.nextToken) 6652 for(Token t = args; t != null; t = t.nextToken)
7132 { 6653 {
7133 if(!((TokenRVal)t).IsRValTrivial(scg, null)) 6654 if(!((TokenRVal)t).IsRValTrivial(scg, null))
7134 return false; 6655 return false;
7135 } 6656 }
7136 6657
7137 /* 6658 // See if the function call itself and the function body are trivial.
7138 * See if the function call itself and the function body are trivial.
7139 */
7140 return meth.IsCallTrivial(scg, myArgSig); 6659 return meth.IsCallTrivial(scg, myArgSig);
7141 } 6660 }
7142 6661
@@ -7717,9 +7236,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7717 7236
7718 public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) 7237 public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig)
7719 { 7238 {
7720 /* 7239 // Comparisons and the like always return bool.
7721 * Comparisons and the like always return bool.
7722 */
7723 string opstr = opcode.ToString(); 7240 string opstr = opcode.ToString();
7724 if((opstr == "==") || (opstr == "!=") || (opstr == ">=") || (opstr == ">") || 7241 if((opstr == "==") || (opstr == "!=") || (opstr == ">=") || (opstr == ">") ||
7725 (opstr == "&&") || (opstr == "||") || (opstr == "<=") || (opstr == "<") || 7242 (opstr == "&&") || (opstr == "||") || (opstr == "<=") || (opstr == "<") ||
@@ -7728,25 +7245,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7728 return new TokenTypeBool(opcode); 7245 return new TokenTypeBool(opcode);
7729 } 7246 }
7730 7247
7731 /* 7248 // Comma is always type of right-hand operand.
7732 * Comma is always type of right-hand operand.
7733 */
7734 if(opstr == ",") 7249 if(opstr == ",")
7735 return rValRight.GetRValType(scg, argsig); 7250 return rValRight.GetRValType(scg, argsig);
7736 7251
7737 /* 7252 // Assignments are always the type of the left-hand operand,
7738 * Assignments are always the type of the left-hand operand, 7253 // including stuff like "+=".
7739 * including stuff like "+=".
7740 */
7741 if(opstr.EndsWith("=")) 7254 if(opstr.EndsWith("="))
7742 { 7255 {
7743 return rValLeft.GetRValType(scg, argsig); 7256 return rValLeft.GetRValType(scg, argsig);
7744 } 7257 }
7745 7258
7746 /* 7259 // string+something or something+string is always string.
7747 * string+something or something+string is always string. 7260 // except list+something or something+list is always a list.
7748 * except list+something or something+list is always a list.
7749 */
7750 string lType = rValLeft.GetRValType(scg, argsig).ToString(); 7261 string lType = rValLeft.GetRValType(scg, argsig).ToString();
7751 string rType = rValRight.GetRValType(scg, argsig).ToString(); 7262 string rType = rValRight.GetRValType(scg, argsig).ToString();
7752 if((opstr == "+") && ((lType == "list") || (rType == "list"))) 7263 if((opstr == "+") && ((lType == "list") || (rType == "list")))
@@ -7759,9 +7270,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
7759 return new TokenTypeStr(opcode); 7270 return new TokenTypeStr(opcode);
7760 } 7271 }
7761 7272
7762 /* 7273 // Everything else depends on both operands.
7763 * Everything else depends on both operands.
7764 */
7765 string key = lType + opstr + rType; 7274 string key = lType + opstr + rType;
7766 BinOpStr binOpStr; 7275 BinOpStr binOpStr;
7767 if(BinOpStr.defined.TryGetValue(key, out binOpStr)) 7276 if(BinOpStr.defined.TryGetValue(key, out binOpStr))
@@ -8234,7 +7743,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8234 */ 7743 */
8235 public class TokenStmtBlock: TokenStmt 7744 public class TokenStmtBlock: TokenStmt
8236 { 7745 {
8237
8238 public Token statements; // null-terminated list of statements, can also have TokenDeclVar's in here 7746 public Token statements; // null-terminated list of statements, can also have TokenDeclVar's in here
8239 public TokenStmtBlock outerStmtBlock; // next outer stmtBlock or null if top-level, ie, function definition 7747 public TokenStmtBlock outerStmtBlock; // next outer stmtBlock or null if top-level, ie, function definition
8240 public TokenDeclVar function; // function it is part of 7748 public TokenDeclVar function; // function it is part of
@@ -8262,7 +7770,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8262 */ 7770 */
8263 public class TokenStmtLabel: TokenStmt 7771 public class TokenStmtLabel: TokenStmt
8264 { 7772 {
8265
8266 public TokenName name; // the label's name 7773 public TokenName name; // the label's name
8267 public TokenStmtBlock block; // which block it is defined in 7774 public TokenStmtBlock block; // which block it is defined in
8268 public bool hasBkwdRefs = false; 7775 public bool hasBkwdRefs = false;
@@ -8437,7 +7944,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8437 7944
8438 public class TokenStmtNull: TokenStmt 7945 public class TokenStmtNull: TokenStmt
8439 { 7946 {
8440
8441 public TokenStmtNull(Token original) : base(original) { } 7947 public TokenStmtNull(Token original) : base(original) { }
8442 7948
8443 public override void DebString(StringBuilder sb) 7949 public override void DebString(StringBuilder sb)
@@ -8448,7 +7954,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8448 7954
8449 public class TokenStmtRet: TokenStmt 7955 public class TokenStmtRet: TokenStmt
8450 { 7956 {
8451
8452 public TokenRVal rVal; // null if void 7957 public TokenRVal rVal; // null if void
8453 7958
8454 public TokenStmtRet(Token original) : base(original) { } 7959 public TokenStmtRet(Token original) : base(original) { }
@@ -8470,7 +7975,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8470 */ 7975 */
8471 public class TokenStmtState: TokenStmt 7976 public class TokenStmtState: TokenStmt
8472 { 7977 {
8473
8474 public TokenName state; // null for default 7978 public TokenName state; // null for default
8475 7979
8476 public TokenStmtState(Token original) : base(original) { } 7980 public TokenStmtState(Token original) : base(original) { }
@@ -8488,7 +7992,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8488 */ 7992 */
8489 public class TokenStmtSwitch: TokenStmt 7993 public class TokenStmtSwitch: TokenStmt
8490 { 7994 {
8491
8492 public TokenRValParen testRVal; // the integer index expression 7995 public TokenRValParen testRVal; // the integer index expression
8493 public TokenSwitchCase cases = null; // list of all cases, linked by .nextCase 7996 public TokenSwitchCase cases = null; // list of all cases, linked by .nextCase
8494 public TokenSwitchCase lastCase = null; // used during reduce to point to last in 'cases' list 7997 public TokenSwitchCase lastCase = null; // used during reduce to point to last in 'cases' list
@@ -8558,7 +8061,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8558 8061
8559 public class TokenStmtThrow: TokenStmt 8062 public class TokenStmtThrow: TokenStmt
8560 { 8063 {
8561
8562 public TokenRVal rVal; // null if rethrow style 8064 public TokenRVal rVal; // null if rethrow style
8563 8065
8564 public TokenStmtThrow(Token original) : base(original) { } 8066 public TokenStmtThrow(Token original) : base(original) { }
@@ -8576,7 +8078,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8576 */ 8078 */
8577 public class TokenStmtTry: TokenStmt 8079 public class TokenStmtTry: TokenStmt
8578 { 8080 {
8579
8580 public TokenStmtBlock tryStmt; 8081 public TokenStmtBlock tryStmt;
8581 public TokenDeclVar catchVar; // null iff catchStmt is null 8082 public TokenDeclVar catchVar; // null iff catchStmt is null
8582 public TokenStmtBlock catchStmt; // can be null 8083 public TokenStmtBlock catchStmt; // can be null
@@ -8620,7 +8121,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
8620 8121
8621 public class TokenStmtWhile: TokenStmt 8122 public class TokenStmtWhile: TokenStmt
8622 { 8123 {
8623
8624 public TokenRValParen testRVal; 8124 public TokenRValParen testRVal;
8625 public TokenStmt bodyStmt; 8125 public TokenStmt bodyStmt;
8626 8126
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs
index 1bcb5b6..6c233bc 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs
@@ -219,9 +219,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
219 { 219 {
220 sourceHash = null; 220 sourceHash = null;
221 221
222 /* 222 // Now do the tokenization.
223 * Now do the tokenization.
224 */
225 TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0); 223 TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0);
226 tokenBegin.cameFrom = cameFrom; 224 tokenBegin.cameFrom = cameFrom;
227 tokenBegin.saveSource = saveSource; 225 tokenBegin.saveSource = saveSource;
@@ -384,17 +382,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
384 if(c == '\n') 382 if(c == '\n')
385 { 383 {
386 384
387 /* 385 // Increment source line number and set char index of beg of next line.
388 * Increment source line number and set char index of beg of next line.
389 */
390 lineNo++; 386 lineNo++;
391 bolIdx = i + 1; 387 bolIdx = i + 1;
392 388
393 /* 389 // Check for '#' lineno filename newline
394 * Check for '#' lineno filename newline 390 // lineno is line number of next line in file
395 * lineno is line number of next line in file 391 // If found, save values and remove tokens from stream
396 * If found, save values and remove tokens from stream
397 */
398 if((lastToken is TokenStr) && 392 if((lastToken is TokenStr) &&
399 (lastToken.prevToken is TokenInt) && 393 (lastToken.prevToken is TokenInt) &&
400 (lastToken.prevToken.prevToken is TokenKwHash)) 394 (lastToken.prevToken.prevToken is TokenKwHash))
@@ -407,15 +401,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
407 continue; 401 continue;
408 } 402 }
409 403
410 /* 404 // Skip over whitespace.
411 * Skip over whitespace.
412 */
413 if(c <= ' ') 405 if(c <= ' ')
414 continue; 406 continue;
415 407
416 /* 408 // Skip over comments.
417 * Skip over comments.
418 */
419 if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//")) 409 if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//"))
420 { 410 {
421 while((i < source.Length) && (source[i] != '\n')) 411 while((i < source.Length) && (source[i] != '\n'))
@@ -440,9 +430,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
440 continue; 430 continue;
441 } 431 }
442 432
443 /* 433 // Check for numbers.
444 * Check for numbers.
445 */
446 if((c >= '0') && (c <= '9')) 434 if((c >= '0') && (c <= '9'))
447 { 435 {
448 int j = TryParseFloat(i); 436 int j = TryParseFloat(i);
@@ -459,9 +447,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
459 continue; 447 continue;
460 } 448 }
461 449
462 /* 450 // Check for quoted strings.
463 * Check for quoted strings.
464 */
465 if(c == '"') 451 if(c == '"')
466 { 452 {
467 StringBuilder sb = new StringBuilder(); 453 StringBuilder sb = new StringBuilder();
@@ -509,9 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
509 continue; 495 continue;
510 } 496 }
511 497
512 /* 498 // Check for quoted characters.
513 * Check for quoted characters.
514 */
515 if(c == '\'') 499 if(c == '\'')
516 { 500 {
517 char cb = (char)0; 501 char cb = (char)0;
@@ -560,9 +544,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
560 continue; 544 continue;
561 } 545 }
562 546
563 /* 547 // Check for keywords/names.
564 * Check for keywords/names.
565 */
566 if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns)) 548 if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns))
567 { 549 {
568 int j; 550 int j;
@@ -629,9 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
629 continue; 611 continue;
630 } 612 }
631 613
632 /* 614 // Check for option enables.
633 * Check for option enables.
634 */
635 if((c == ';') && (lastToken is TokenName) && 615 if((c == ';') && (lastToken is TokenName) &&
636 (lastToken.prevToken is TokenName) && 616 (lastToken.prevToken is TokenName) &&
637 (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) 617 (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0))
@@ -669,9 +649,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
669 continue; 649 continue;
670 } 650 }
671 651
672 /* 652 // Lastly, check for delimeters.
673 * Lastly, check for delimeters.
674 */
675 { 653 {
676 int j; 654 int j;
677 int len = 0; 655 int len = 0;
@@ -692,9 +670,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
692 } 670 }
693 } 671 }
694 672
695 /* 673 // Don't know what it is!
696 * Don't know what it is!
697 */
698 TokenError(i, "unknown character '" + c + "'"); 674 TokenError(i, "unknown character '" + c + "'");
699 } 675 }
700 } 676 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs
index 8761e7a..dd0e5e0 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs
@@ -177,11 +177,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
177 */ 177 */
178 public static bool IsAssignableFrom(TokenType dstType, TokenType srcType) 178 public static bool IsAssignableFrom(TokenType dstType, TokenType srcType)
179 { 179 {
180 /* 180 // Do a 'dry run' of the casting operation, discarding any emits and not printing any errors.
181 * Do a 'dry run' of the casting operation, discarding any emits and not printing any errors. 181 // But if the casting tries to print error(s), return false.
182 * But if the casting tries to print error(s), return false. 182 // Otherwise assume the cast is allowed and return true.
183 * Otherwise assume the cast is allowed and return true.
184 */
185 SCGIAF scg = new SCGIAF(); 183 SCGIAF scg = new SCGIAF();
186 scg.ok = true; 184 scg.ok = true;
187 scg._ilGen = migiaf; 185 scg._ilGen = migiaf;
@@ -305,9 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
305 string oldString = oldType.ToString(); 303 string oldString = oldType.ToString();
306 string newString = newType.ToString(); 304 string newString = newType.ToString();
307 305
308 /* 306 // 'key' -> 'bool' is the only time we care about key being different than string.
309 * 'key' -> 'bool' is the only time we care about key being different than string.
310 */
311 if((oldString == "key") && (newString == "bool")) 307 if((oldString == "key") && (newString == "bool"))
312 { 308 {
313 LSLUnwrap(scg, errorAt, oldType); 309 LSLUnwrap(scg, errorAt, oldType);
@@ -316,18 +312,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
316 return; 312 return;
317 } 313 }
318 314
319 /* 315 // Treat key and string as same type for all other type casts.
320 * Treat key and string as same type for all other type casts.
321 */
322 if(oldString == "key") 316 if(oldString == "key")
323 oldString = "string"; 317 oldString = "string";
324 if(newString == "key") 318 if(newString == "key")
325 newString = "string"; 319 newString = "string";
326 320
327 /* 321 // If the types are the same, there is no conceptual casting needed.
328 * If the types are the same, there is no conceptual casting needed. 322 // However, there may be wraping/unwraping to/from the LSL wrappers.
329 * However, there may be wraping/unwraping to/from the LSL wrappers.
330 */
331 if(oldString == newString) 323 if(oldString == newString)
332 { 324 {
333 if(oldType.ToLSLWrapType() != newType.ToLSLWrapType()) 325 if(oldType.ToLSLWrapType() != newType.ToLSLWrapType())
@@ -338,9 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
338 return; 330 return;
339 } 331 }
340 332
341 /* 333 // Script-defined classes can be cast up and down the tree.
342 * Script-defined classes can be cast up and down the tree.
343 */
344 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass)) 334 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass))
345 { 335 {
346 TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; 336 TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
@@ -369,11 +359,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
369 goto illcast; 359 goto illcast;
370 } 360 }
371 361
372 /* 362 // One script-defined interface type cannot be cast to another script-defined interface type,
373 * One script-defined interface type cannot be cast to another script-defined interface type, 363 // unless the old interface declares that it implements the new interface. That proves that
374 * unless the old interface declares that it implements the new interface. That proves that 364 // the underlying object, no matter what type, implements the new interface.
375 * the underlying object, no matter what type, implements the new interface.
376 */
377 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface)) 365 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface))
378 { 366 {
379 TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl; 367 TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl;
@@ -385,11 +373,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
385 return; 373 return;
386 } 374 }
387 375
388 /* 376 // A script-defined class type can be implicitly cast to a script-defined interface type that it
389 * A script-defined class type can be implicitly cast to a script-defined interface type that it 377 // implements. The result is an array of delegates that give the class's implementation of the
390 * implements. The result is an array of delegates that give the class's implementation of the 378 // various methods defined by the interface.
391 * various methods defined by the interface.
392 */
393 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface)) 379 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface))
394 { 380 {
395 TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; 381 TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl;
@@ -402,13 +388,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
402 return; 388 return;
403 } 389 }
404 390
405 /* 391 // A script-defined interface type can be explicitly cast to a script-defined class type by
406 * A script-defined interface type can be explicitly cast to a script-defined class type by 392 // extracting the Target property from element 0 of the delegate array that is the interface
407 * extracting the Target property from element 0 of the delegate array that is the interface 393 // object and making sure it casts to the correct script-defined class type.
408 * object and making sure it casts to the correct script-defined class type. 394 //
409 * 395 // But then only if the class type implements the interface type.
410 * But then only if the class type implements the interface type.
411 */
412 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass)) 396 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass))
413 { 397 {
414 TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType; 398 TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType;
@@ -423,17 +407,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
423 return; 407 return;
424 } 408 }
425 409
426 /* 410 // A script-defined interface type can be implicitly cast to object.
427 * A script-defined interface type can be implicitly cast to object.
428 */
429 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject)) 411 if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject))
430 { 412 {
431 return; 413 return;
432 } 414 }
433 415
434 /* 416 // An object can be explicitly cast to a script-defined interface.
435 * An object can be explicitly cast to a script-defined interface.
436 */
437 if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface)) 417 if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface))
438 { 418 {
439 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); 419 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
@@ -442,18 +422,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
442 return; 422 return;
443 } 423 }
444 424
445 /* 425 // Cast to void is always allowed, such as discarding value from 'i++' or function return value.
446 * Cast to void is always allowed, such as discarding value from 'i++' or function return value.
447 */
448 if(newType is TokenTypeVoid) 426 if(newType is TokenTypeVoid)
449 { 427 {
450 scg.ilGen.Emit(errorAt, OpCodes.Pop); 428 scg.ilGen.Emit(errorAt, OpCodes.Pop);
451 return; 429 return;
452 } 430 }
453 431
454 /* 432 // Cast from undef to object or script-defined type is always allowed.
455 * Cast from undef to object or script-defined type is always allowed.
456 */
457 if((oldType is TokenTypeUndef) && 433 if((oldType is TokenTypeUndef) &&
458 ((newType is TokenTypeObject) || 434 ((newType is TokenTypeObject) ||
459 (newType is TokenTypeSDTypeClass) || 435 (newType is TokenTypeSDTypeClass) ||
@@ -462,19 +438,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
462 return; 438 return;
463 } 439 }
464 440
465 /* 441 // Script-defined classes can be implicitly cast to objects.
466 * Script-defined classes can be implicitly cast to objects.
467 */
468 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject)) 442 if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject))
469 { 443 {
470 return; 444 return;
471 } 445 }
472 446
473 /* 447 // Script-defined classes can be explicitly cast from objects and other script-defined classes.
474 * Script-defined classes can be explicitly cast from objects and other script-defined classes. 448 // Note that we must manually check that it is the correct SDTypeClass however because as far as
475 * Note that we must manually check that it is the correct SDTypeClass however because as far as 449 // mono is concerned, all SDTypeClass's are the same.
476 * mono is concerned, all SDTypeClass's are the same.
477 */
478 if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass)) 450 if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass))
479 { 451 {
480 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); 452 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
@@ -483,9 +455,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
483 return; 455 return;
484 } 456 }
485 457
486 /* 458 // Delegates can be implicitly cast to/from objects.
487 * Delegates can be implicitly cast to/from objects.
488 */
489 if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject)) 459 if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject))
490 { 460 {
491 return; 461 return;
@@ -496,9 +466,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
496 return; 466 return;
497 } 467 }
498 468
499 /* 469 // Some actual conversion is needed, see if it is in table of legal casts.
500 * Some actual conversion is needed, see if it is in table of legal casts.
501 */
502 string key = oldString + " " + newString; 470 string key = oldString + " " + newString;
503 if(!legalTypeCasts.TryGetValue(key, out castDelegate)) 471 if(!legalTypeCasts.TryGetValue(key, out castDelegate))
504 { 472 {
@@ -508,11 +476,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
508 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); 476 ExplCheck(scg, errorAt, explicitAllowed, oldString, newString);
509 } 477 }
510 478
511 /* 479 // Ok, output cast. But make sure it is in native form without any LSL wrapping
512 * Ok, output cast. But make sure it is in native form without any LSL wrapping 480 // before passing to our casting routine. Then if caller is expecting an LSL-
513 * before passing to our casting routine. Then if caller is expecting an LSL- 481 // wrapped value on the stack upon return, wrap it up after our casting.
514 * wrapped value on the stack upon return, wrap it up after our casting.
515 */
516 LSLUnwrap(scg, errorAt, oldType); 482 LSLUnwrap(scg, errorAt, oldType);
517 castDelegate(scg, errorAt); 483 castDelegate(scg, errorAt);
518 LSLWrap(scg, errorAt, newType); 484 LSLWrap(scg, errorAt, newType);
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs
index 2561d02..a0bc7ba 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs
@@ -130,9 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
130 throw new Exception("var dict is frozen"); 130 throw new Exception("var dict is frozen");
131 } 131 }
132 132
133 /* 133 // Make sure we have a sub-dictionary based on the bare name (ie, no signature)
134 * Make sure we have a sub-dictionary based on the bare name (ie, no signature)
135 */
136 Dictionary<ArgTypes, TDVEntry> typedic; 134 Dictionary<ArgTypes, TDVEntry> typedic;
137 if(!master.TryGetValue(var.name.val, out typedic)) 135 if(!master.TryGetValue(var.name.val, out typedic))
138 { 136 {
@@ -140,19 +138,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
140 master.Add(var.name.val, typedic); 138 master.Add(var.name.val, typedic);
141 } 139 }
142 140
143 /* 141 // See if there is an entry in the sub-dictionary that matches the argument signature.
144 * See if there is an entry in the sub-dictionary that matches the argument signature. 142 // Note that fields have null argument lists.
145 * Note that fields have null argument lists. 143 // Methods always have a non-null argument list, even if only 0 entries long.
146 * Methods always have a non-null argument list, even if only 0 entries long.
147 */
148 ArgTypes types; 144 ArgTypes types;
149 types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types); 145 types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types);
150 if(typedic.ContainsKey(types)) 146 if(typedic.ContainsKey(types))
151 return false; 147 return false;
152 148
153 /* 149 // It is unique, add to its name-specific sub-dictionary.
154 * It is unique, add to its name-specific sub-dictionary.
155 */
156 TDVEntry entry; 150 TDVEntry entry;
157 entry.count = ++count; 151 entry.count = ++count;
158 entry.var = var; 152 entry.var = var;
@@ -175,28 +169,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
175 */ 169 */
176 public VarDict FreezeLocals() 170 public VarDict FreezeLocals()
177 { 171 {
178 /* 172 // If not local var frame, return original frame as is.
179 * If not local var frame, return original frame as is. 173 // This will allow forward references as the future additions
180 * This will allow forward references as the future additions 174 // will be seen by lookups done in this dictionary.
181 * will be seen by lookups done in this dictionary.
182 */
183 if(!locals) 175 if(!locals)
184 return this; 176 return this;
185 177
186 /* 178 // If local var frame, return a copy frozen at this point.
187 * If local var frame, return a copy frozen at this point. 179 // This disallows forward referenes as those future additions
188 * This disallows forward referenes as those future additions 180 // will not be seen by lookups done in the frozen dictionary.
189 * will not be seen by lookups done in the frozen dictionary.
190 */
191 if((frozenLocals == null) || (frozenLocals.count != this.count)) 181 if((frozenLocals == null) || (frozenLocals.count != this.count))
192 { 182 {
193 183 // Make a copy of the current var dictionary frame.
194 /* 184 // We copy a reference to the dictionary, and though it may
195 * Make a copy of the current var dictionary frame. 185 // contain additions made after this point, those additions
196 * We copy a reference to the dictionary, and though it may 186 // will have a count .gt. frozen count and will be ignored.
197 * contain additions made after this point, those additions
198 * will have a count .gt. frozen count and will be ignored.
199 */
200 frozenLocals = new VarDict(true); 187 frozenLocals = new VarDict(true);
201 188
202 frozenLocals.outerVarDict = this.outerVarDict; 189 frozenLocals.outerVarDict = this.outerVarDict;
@@ -205,11 +192,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
205 frozenLocals.count = this.count; 192 frozenLocals.count = this.count;
206 frozenLocals.frozenLocals = frozenLocals; 193 frozenLocals.frozenLocals = frozenLocals;
207 194
208 /* 195 // Mark it as being frozen.
209 * Mark it as being frozen. 196 // - assert fail if any attempt is made to add to it
210 * - assert fail if any attempt is made to add to it 197 // - ignore any additions to the dictionary with greater count
211 * - ignore any additions to the dictionary with greater count
212 */
213 frozenLocals.isFrozen = true; 198 frozenLocals.isFrozen = true;
214 } 199 }
215 return frozenLocals; 200 return frozenLocals;
@@ -257,46 +242,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
257 */ 242 */
258 public TokenDeclVar FindExact(string name, TokenType[] argTypes) 243 public TokenDeclVar FindExact(string name, TokenType[] argTypes)
259 { 244 {
260 /* 245 // Look for list of stuff that matches the given name.
261 * Look for list of stuff that matches the given name.
262 */
263 Dictionary<ArgTypes, TDVEntry> typedic; 246 Dictionary<ArgTypes, TDVEntry> typedic;
264 if(!master.TryGetValue(name, out typedic)) 247 if(!master.TryGetValue(name, out typedic))
265 return null; 248 return null;
266 249
267 /* 250 // Loop through all fields/methods declared by that name, regardless of arg signature.
268 * Loop through all fields/methods declared by that name, regardless of arg signature.
269 */
270 foreach(TDVEntry entry in typedic.Values) 251 foreach(TDVEntry entry in typedic.Values)
271 { 252 {
272 if(entry.count > this.count) 253 if(entry.count > this.count)
273 continue; 254 continue;
274 TokenDeclVar var = entry.var; 255 TokenDeclVar var = entry.var;
275 256
276 /* 257 // Get argument types of declaration.
277 * Get argument types of declaration. 258 // fields are always null
278 * fields are always null 259 // methods are always non-null, though may be zero-length
279 * methods are always non-null, though may be zero-length
280 */
281 TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types; 260 TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types;
282 261
283 /* 262 // Convert any key args to string args.
284 * Convert any key args to string args.
285 */
286 declArgs = KeyTypesToStringTypes(declArgs); 263 declArgs = KeyTypesToStringTypes(declArgs);
287 264
288 /* 265 // If both are null, they are signature-less (ie, both are fields), and so match.
289 * If both are null, they are signature-less (ie, both are fields), and so match.
290 */
291 if((declArgs == null) && (argTypes == null)) 266 if((declArgs == null) && (argTypes == null))
292 return var; 267 return var;
293 268
294 /* 269 // If calling a delegate, it is a match, regardless of delegate arg types.
295 * If calling a delegate, it is a match, regardless of delegate arg types. 270 // If it turns out the arg types do not match, the compiler will give an error
296 * If it turns out the arg types do not match, the compiler will give an error 271 // trying to cast the arguments to the delegate arg types.
297 * trying to cast the arguments to the delegate arg types. 272 // We don't allow overloading same field name with different delegate types.
298 * We don't allow overloading same field name with different delegate types.
299 */
300 if((declArgs == null) && (argTypes != null)) 273 if((declArgs == null) && (argTypes != null))
301 { 274 {
302 TokenType fieldType = var.type; 275 TokenType fieldType = var.type;
@@ -304,15 +277,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
304 return var; 277 return var;
305 } 278 }
306 279
307 /* 280 // If not both null, no match, keep looking.
308 * If not both null, no match, keep looking.
309 */
310 if((declArgs == null) || (argTypes == null)) 281 if((declArgs == null) || (argTypes == null))
311 continue; 282 continue;
312 283
313 /* 284 // Both not null, match argument types to make sure we have correct overload.
314 * Both not null, match argument types to make sure we have correct overload.
315 */
316 int i = declArgs.Length; 285 int i = declArgs.Length;
317 if(i != argTypes.Length) 286 if(i != argTypes.Length)
318 continue; 287 continue;
@@ -331,9 +300,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
331 return var; 300 return var;
332 } 301 }
333 302
334 /* 303 // No match.
335 * No match.
336 */
337 return null; 304 return null;
338 } 305 }
339 306
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
index b797224..3d0525b 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs
@@ -108,10 +108,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
108 { 108 {
109 key = FixKey(key); 109 key = FixKey(key);
110 110
111 /* 111 // Update heap use throwing an exception on failure
112 * Update heap use throwing an exception on failure 112 // before making any changes to the array.
113 * before making any changes to the array.
114 */
115 int keysize = HeapTrackerObject.Size(key); 113 int keysize = HeapTrackerObject.Size(key);
116 int newheapuse = heapUse; 114 int newheapuse = heapUse;
117 object oldval; 115 object oldval;
@@ -125,10 +123,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
125 } 123 }
126 heapUse = inst.UpdateHeapUse(heapUse, newheapuse); 124 heapUse = inst.UpdateHeapUse(heapUse, newheapuse);
127 125
128 /* 126 // Save new value in array, replacing one of same key if there.
129 * Save new value in array, replacing one of same key if there. 127 // null means remove the value, ie, script did array[key] = undef.
130 * null means remove the value, ie, script did array[key] = undef.
131 */
132 if(value != null) 128 if(value != null)
133 { 129 {
134 dnary[key] = value; 130 dnary[key] = value;
@@ -137,19 +133,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
137 { 133 {
138 dnary.Remove(key); 134 dnary.Remove(key);
139 135
140 /* 136 // Shrink the enumeration array, but always leave at least one element.
141 * Shrink the enumeration array, but always leave at least one element.
142 */
143 if((array != null) && (dnary.Count < array.Length / 2)) 137 if((array != null) && (dnary.Count < array.Length / 2))
144 { 138 {
145 Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2); 139 Array.Resize<KeyValuePair<object, object>>(ref array, array.Length / 2);
146 } 140 }
147 } 141 }
148 142
149 /* 143 // The enumeration array is invalid because the dictionary has been modified.
150 * The enumeration array is invalid because the dictionary has been modified. 144 // Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved.
151 * Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved.
152 */
153 arrayValid = 0; 145 arrayValid = 0;
154 } 146 }
155 147
@@ -236,29 +228,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
236 */ 228 */
237 private bool ForEach(int number) 229 private bool ForEach(int number)
238 { 230 {
239 /* 231 // If we don't have any array, we can't have ever done
240 * If we don't have any array, we can't have ever done 232 // any calls here before, so allocate an array big enough
241 * any calls here before, so allocate an array big enough 233 // and set everything else to the beginning.
242 * and set everything else to the beginning.
243 */
244 if(array == null) 234 if(array == null)
245 { 235 {
246 array = new KeyValuePair<object, object>[dnary.Count]; 236 array = new KeyValuePair<object, object>[dnary.Count];
247 arrayValid = 0; 237 arrayValid = 0;
248 } 238 }
249 239
250 /* 240 // If dictionary modified since last enumeration, get a new enumerator.
251 * If dictionary modified since last enumeration, get a new enumerator.
252 */
253 if(arrayValid == 0) 241 if(arrayValid == 0)
254 { 242 {
255 enumr = dnary.GetEnumerator(); 243 enumr = dnary.GetEnumerator();
256 enumrValid = true; 244 enumrValid = true;
257 } 245 }
258 246
259 /* 247 // Make sure we have filled the array up enough for requested element.
260 * Make sure we have filled the array up enough for requested element.
261 */
262 while((arrayValid <= number) && enumrValid && enumr.MoveNext()) 248 while((arrayValid <= number) && enumrValid && enumr.MoveNext())
263 { 249 {
264 if(arrayValid >= array.Length) 250 if(arrayValid >= array.Length)
@@ -268,9 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
268 array[arrayValid++] = enumr.Current; 254 array[arrayValid++] = enumr.Current;
269 } 255 }
270 256
271 /* 257 // If we don't have that many elements, return end-of-array status.
272 * If we don't have that many elements, return end-of-array status.
273 */
274 return number < arrayValid; 258 return number < arrayValid;
275 } 259 }
276 260
@@ -281,10 +265,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
281 public delegate void SendArrayObjDelegate(object graph); 265 public delegate void SendArrayObjDelegate(object graph);
282 public void SendArrayObj(SendArrayObjDelegate sendObj) 266 public void SendArrayObj(SendArrayObjDelegate sendObj)
283 { 267 {
284 /* 268 // Set the count then the elements themselves.
285 * Set the count then the elements themselves. 269 // UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
286 * UnfixKey() because sendObj doesn't handle XMRArrayListKeys.
287 */
288 sendObj(dnary.Count); 270 sendObj(dnary.Count);
289 foreach(KeyValuePair<object, object> kvp in dnary) 271 foreach(KeyValuePair<object, object> kvp in dnary)
290 { 272 {
@@ -304,17 +286,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
304 { 286 {
305 heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); 287 heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP);
306 288
307 /* 289 // Cause any enumeration to refill the array from the sorted dictionary.
308 * Cause any enumeration to refill the array from the sorted dictionary. 290 // Since it is a sorted dictionary, any enumerations will be in the same
309 * Since it is a sorted dictionary, any enumerations will be in the same 291 // order as on the sending side.
310 * order as on the sending side.
311 */
312 arrayValid = 0; 292 arrayValid = 0;
313 enumrValid = false; 293 enumrValid = false;
314 294
315 /* 295 // Fill dictionary.
316 * Fill dictionary.
317 */
318 dnary.Clear(); 296 dnary.Clear();
319 int count = (int)recvObj(); 297 int count = (int)recvObj();
320 while(--count >= 0) 298 while(--count >= 0)
@@ -375,9 +353,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
375 */ 353 */
376 public int Compare(object x, object y) // IComparer<object> 354 public int Compare(object x, object y) // IComparer<object>
377 { 355 {
378 /* 356 // Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key.
379 * Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key.
380 */
381 string xtn = x.GetType().Name; 357 string xtn = x.GetType().Name;
382 string ytn = y.GetType().Name; 358 string ytn = y.GetType().Name;
383 int ctn = String.CompareOrdinal(xtn, ytn); 359 int ctn = String.CompareOrdinal(xtn, ytn);
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
index 19ff336..ea306c8 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs
@@ -56,9 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
56 string outName = null; 56 string outName = null;
57 XMRInstance[] instances; 57 XMRInstance[] instances;
58 58
59 /* 59 // Decode command line options.
60 * Decode command line options.
61 */
62 for(int i = indx; i < args.Length; i++) 60 for(int i = indx; i < args.Length; i++)
63 { 61 {
64 if(args[i] == "-full") 62 if(args[i] == "-full")
@@ -126,10 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
126 124
127 try 125 try
128 { 126 {
129 127 // Scan instance list to find those that match selection criteria.
130 /*
131 * Scan instance list to find those that match selection criteria.
132 */
133 if(!Monitor.TryEnter(m_InstancesDict, 100)) 128 if(!Monitor.TryEnter(m_InstancesDict, 100))
134 { 129 {
135 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); 130 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@@ -151,17 +146,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
151 Monitor.Exit(m_InstancesDict); 146 Monitor.Exit(m_InstancesDict);
152 } 147 }
153 148
154 /* 149 // Maybe sort by descending CPU time.
155 * Maybe sort by descending CPU time.
156 */
157 if(flagTopCPU) 150 if(flagTopCPU)
158 { 151 {
159 Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime); 152 Array.Sort<XMRInstance>(instances, CompareInstancesByCPUTime);
160 } 153 }
161 154
162 /* 155 // Print the entries.
163 * Print the entries.
164 */
165 if(!flagFull) 156 if(!flagFull)
166 { 157 {
167 outFile.WriteLine(" ItemID" + 158 outFile.WriteLine(" ItemID" +
@@ -176,15 +167,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
176 outFile.WriteLine(instances[i].RunTestLs(flagFull)); 167 outFile.WriteLine(instances[i].RunTestLs(flagFull));
177 } 168 }
178 169
179 /* 170 // Print number of scripts that match selection criteria,
180 * Print number of scripts that match selection criteria, 171 // even if we were told to print fewer.
181 * even if we were told to print fewer.
182 */
183 outFile.WriteLine("total of {0} script(s)", numScripts); 172 outFile.WriteLine("total of {0} script(s)", numScripts);
184 173
185 /* 174 // If -queues given, print out queue contents too.
186 * If -queues given, print out queue contents too.
187 */
188 if(flagQueues) 175 if(flagQueues)
189 { 176 {
190 LsQueue(outFile, "start", m_StartQueue, args, indx); 177 LsQueue(outFile, "start", m_StartQueue, args, indx);
@@ -204,9 +191,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
204 int numScripts = 0; 191 int numScripts = 0;
205 XMRInstance[] instances; 192 XMRInstance[] instances;
206 193
207 /* 194 // Decode command line options.
208 * Decode command line options.
209 */
210 int i, j; 195 int i, j;
211 List<string> selargs = new List<string>(args.Length); 196 List<string> selargs = new List<string>(args.Length);
212 MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); 197 MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods();
@@ -271,9 +256,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
271 OpenSim.Region.ScriptEngine.Shared.EventParams eps = 256 OpenSim.Region.ScriptEngine.Shared.EventParams eps =
272 new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); 257 new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams);
273 258
274 /* 259 // Scan instance list to find those that match selection criteria.
275 * Scan instance list to find those that match selection criteria.
276 */
277 if(!Monitor.TryEnter(m_InstancesDict, 100)) 260 if(!Monitor.TryEnter(m_InstancesDict, 100))
278 { 261 {
279 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); 262 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@@ -296,9 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
296 Monitor.Exit(m_InstancesDict); 279 Monitor.Exit(m_InstancesDict);
297 } 280 }
298 281
299 /* 282 // Post event to the matching instances.
300 * Post event to the matching instances.
301 */
302 for(i = 0; i < numScripts; i++) 283 for(i = 0; i < numScripts; i++)
303 { 284 {
304 XMRInstance inst = instances[i]; 285 XMRInstance inst = instances[i];
@@ -415,9 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
415 return; 396 return;
416 } 397 }
417 398
418 /* 399 // Decode command line options.
419 * Decode command line options.
420 */
421 for(int i = indx; i < args.Length; i++) 400 for(int i = indx; i < args.Length; i++)
422 { 401 {
423 if(args[i] == "-all") 402 if(args[i] == "-all")
@@ -437,9 +416,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
437 } 416 }
438 } 417 }
439 418
440 /* 419 // Scan instance list to find those that match selection criteria.
441 * Scan instance list to find those that match selection criteria.
442 */
443 if(!Monitor.TryEnter(m_InstancesDict, 100)) 420 if(!Monitor.TryEnter(m_InstancesDict, 100))
444 { 421 {
445 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); 422 m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict);
@@ -462,9 +439,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
462 Monitor.Exit(m_InstancesDict); 439 Monitor.Exit(m_InstancesDict);
463 } 440 }
464 441
465 /* 442 // Reset the instances as if someone clicked their "Reset" button.
466 * Reset the instances as if someone clicked their "Reset" button.
467 */
468 for(int i = 0; i < numScripts; i++) 443 for(int i = 0; i < numScripts; i++)
469 { 444 {
470 XMRInstance inst = instances[i]; 445 XMRInstance inst = instances[i];
@@ -499,10 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
499 { 474 {
500 try 475 try
501 { 476 {
502 477 // Try to print instance name.
503 /*
504 * Try to print instance name.
505 */
506 if(InstanceMatchesArgs(inst, args, indx)) 478 if(InstanceMatchesArgs(inst, args, indx))
507 { 479 {
508 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName); 480 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName);
@@ -510,10 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
510 } 482 }
511 catch(Exception e) 483 catch(Exception e)
512 { 484 {
513 485 // Sometimes there are instances in the queue that are disposed.
514 /*
515 * Sometimes there are instances in the queue that are disposed.
516 */
517 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message); 486 outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message);
518 } 487 }
519 } 488 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
index a0bb3e0..b3ff765 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs
@@ -473,10 +473,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
473 { 473 {
474 ScriptEventHandler seh; 474 ScriptEventHandler seh;
475 475
476 /* 476 // CallMode_NORMAL: run event handler from the beginning normally
477 * CallMode_NORMAL: run event handler from the beginning normally 477 // CallMode_RESTORE: restore event handler stack from stackFrames
478 * CallMode_RESTORE: restore event handler stack from stackFrames
479 */
480 callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : 478 callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL :
481 XMRInstAbstract.CallMode_RESTORE; 479 XMRInstAbstract.CallMode_RESTORE;
482 480
@@ -723,25 +721,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
723 if(o is LSL_Vector) 721 if(o is LSL_Vector)
724 return "vector"; 722 return "vector";
725 723
726 /* 724 // A script-defined interface is represented as an array of delegates.
727 * A script-defined interface is represented as an array of delegates. 725 // If that is the case, convert it to the object of the script-defined
728 * If that is the case, convert it to the object of the script-defined 726 // class that is implementing the interface. This should let the next
729 * class that is implementing the interface. This should let the next 727 // step get the script-defined type name of the object.
730 * step get the script-defined type name of the object.
731 */
732 if(o is Delegate[]) 728 if(o is Delegate[])
733 o = ((Delegate[])o)[0].Target; 729 o = ((Delegate[])o)[0].Target;
734 730
735 /* 731 // If script-defined class instance, get the script-defined
736 * If script-defined class instance, get the script-defined 732 // type name.
737 * type name.
738 */
739 if(o is XMRSDTypeClObj) 733 if(o is XMRSDTypeClObj)
740 return ((XMRSDTypeClObj)o).sdtcClass.longName.val; 734 return ((XMRSDTypeClObj)o).sdtcClass.longName.val;
741 735
742 /* 736 // If it's a delegate, maybe we can look up its script-defined type name.
743 * If it's a delegate, maybe we can look up its script-defined type name.
744 */
745 Type ot = o.GetType(); 737 Type ot = o.GetType();
746 if(o is Delegate) 738 if(o is Delegate)
747 { 739 {
@@ -750,9 +742,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
750 return os; 742 return os;
751 } 743 }
752 744
753 /* 745 // Don't know what it is, get the C#-level type name.
754 * Don't know what it is, get the C#-level type name.
755 */
756 return ot.ToString(); 746 return ot.ToString();
757 } 747 }
758 748
@@ -964,17 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
964 { 954 {
965 TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex]; 955 TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex];
966 956
967 /* 957 // If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
968 * If it is a script-defined interface object, convert to the original XMRSDTypeClObj.
969 */
970 if(thrown is Delegate[]) 958 if(thrown is Delegate[])
971 { 959 {
972 thrown = ((Delegate[])thrown)[0].Target; 960 thrown = ((Delegate[])thrown)[0].Target;
973 } 961 }
974 962
975 /* 963 // If it is a script-defined delegate object, make sure it is an instance of the expected type.
976 * If it is a script-defined delegate object, make sure it is an instance of the expected type.
977 */
978 if(thrown is Delegate) 964 if(thrown is Delegate)
979 { 965 {
980 Type ot = thrown.GetType(); 966 Type ot = thrown.GetType();
@@ -982,17 +968,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
982 return (ot == tt) ? thrown : null; 968 return (ot == tt) ? thrown : null;
983 } 969 }
984 970
985 /* 971 // If it is a script-defined class object, make sure it is an instance of the expected class.
986 * If it is a script-defined class object, make sure it is an instance of the expected class.
987 */
988 if(thrown is XMRSDTypeClObj) 972 if(thrown is XMRSDTypeClObj)
989 { 973 {
990 974 // Step from the object's actual class rootward.
991 /* 975 // If we find the requested class along the way, the cast is valid.
992 * Step from the object's actual class rootward. 976 // If we run off the end of the root, the cast is not valid.
993 * If we find the requested class along the way, the cast is valid.
994 * If we run off the end of the root, the cast is not valid.
995 */
996 for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) 977 for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends)
997 { 978 {
998 if(ac == sdType) 979 if(ac == sdType)
@@ -1000,9 +981,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1000 } 981 }
1001 } 982 }
1002 983
1003 /* 984 // Don't know what it is, assume it is not what caller wants.
1004 * Don't know what it is, assume it is not what caller wants.
1005 */
1006 return null; 985 return null;
1007 } 986 }
1008 987
@@ -1070,24 +1049,18 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1070 */ 1049 */
1071 public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count) 1050 public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count)
1072 { 1051 {
1073 /* 1052 // The script writer should only pass us script-defined class objects.
1074 * The script writer should only pass us script-defined class objects. 1053 // Throw exception otherwise.
1075 * Throw exception otherwise.
1076 */
1077 XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj; 1054 XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj;
1078 XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj; 1055 XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj;
1079 1056
1080 /* 1057 // Get the script-visible type name of the arrays, brackets and all.
1081 * Get the script-visible type name of the arrays, brackets and all.
1082 */
1083 string srctypename = srcsdt.sdtcClass.longName.val; 1058 string srctypename = srcsdt.sdtcClass.longName.val;
1084 string dsttypename = dstsdt.sdtcClass.longName.val; 1059 string dsttypename = dstsdt.sdtcClass.longName.val;
1085 1060
1086 /* 1061 // The part before the first '[' of each should match exactly,
1087 * The part before the first '[' of each should match exactly, 1062 // meaning the basic data type (eg, float, List<string>) is the same.
1088 * meaning the basic data type (eg, float, List<string>) is the same. 1063 // And there must be a '[' in each meaning that it is a script-defined array type.
1089 * And there must be a '[' in each meaning that it is a script-defined array type.
1090 */
1091 int i = srctypename.IndexOf('['); 1064 int i = srctypename.IndexOf('[');
1092 int j = dsttypename.IndexOf('['); 1065 int j = dsttypename.IndexOf('[');
1093 if((i < 0) || (j < 0)) 1066 if((i < 0) || (j < 0))
@@ -1095,12 +1068,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1095 if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j))) 1068 if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j)))
1096 throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); 1069 throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
1097 1070
1098 /* 1071 // The number of brackets must match exactly.
1099 * The number of brackets must match exactly. 1072 // This permits copying from something like a float[,][] to something like a float[][].
1100 * This permits copying from something like a float[,][] to something like a float[][]. 1073 // But you cannot copy from a float[][] to a float[] or wisa wersa.
1101 * But you cannot copy from a float[][] to a float[] or wisa wersa. 1074 // Counting either '[' or ']' would work equally well.
1102 * Counting either '[' or ']' would work equally well.
1103 */
1104 int srclen = srctypename.Length; 1075 int srclen = srctypename.Length;
1105 int dstlen = dsttypename.Length; 1076 int dstlen = dsttypename.Length;
1106 int srcjags = 0; 1077 int srcjags = 0;
@@ -1114,9 +1085,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1114 if(dstjags != srcjags) 1085 if(dstjags != srcjags)
1115 throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); 1086 throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename);
1116 1087
1117 /* 1088 // Perform the copy.
1118 * Perform the copy.
1119 */
1120 Array srcarray = (Array)srcsdt.instVars.iarObjects[0]; 1089 Array srcarray = (Array)srcsdt.instVars.iarObjects[0];
1121 Array dstarray = (Array)dstsdt.instVars.iarObjects[0]; 1090 Array dstarray = (Array)dstsdt.instVars.iarObjects[0];
1122 Array.Copy(srcarray, srcstart, dstarray, dststart, count); 1091 Array.Copy(srcarray, srcstart, dstarray, dststart, count);
@@ -1131,19 +1100,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1131 */ 1100 */
1132 public static LSL_List xmrArray2List(object srcar, int start, int count) 1101 public static LSL_List xmrArray2List(object srcar, int start, int count)
1133 { 1102 {
1134 /* 1103 // Get the script-visible type of the array.
1135 * Get the script-visible type of the array. 1104 // We only do arrays.
1136 * We only do arrays.
1137 */
1138 XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; 1105 XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
1139 TokenDeclSDTypeClass sdtClass = array.sdtcClass; 1106 TokenDeclSDTypeClass sdtClass = array.sdtcClass;
1140 if(sdtClass.arrayOfRank == 0) 1107 if(sdtClass.arrayOfRank == 0)
1141 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); 1108 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
1142 1109
1143 /* 1110 // Validate objects they want to put in the list.
1144 * Validate objects they want to put in the list. 1111 // We can't allow anything funky that OpenSim runtime doesn't expect.
1145 * We can't allow anything funky that OpenSim runtime doesn't expect.
1146 */
1147 Array srcarray = (Array)array.instVars.iarObjects[0]; 1112 Array srcarray = (Array)array.instVars.iarObjects[0];
1148 object[] output = new object[count]; 1113 object[] output = new object[count];
1149 for(int i = 0; i < count; i++) 1114 for(int i = 0; i < count; i++)
@@ -1179,9 +1144,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1179 throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name); 1144 throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name);
1180 } 1145 }
1181 1146
1182 /* 1147 // Make a list out of that now immutable array.
1183 * Make a list out of that now immutable array.
1184 */
1185 return new LSL_List(output); 1148 return new LSL_List(output);
1186 } 1149 }
1187 1150
@@ -1195,19 +1158,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1195 */ 1158 */
1196 public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count) 1159 public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count)
1197 { 1160 {
1198 /* 1161 // Get the script-visible type of the destination.
1199 * Get the script-visible type of the destination. 1162 // We only do arrays.
1200 * We only do arrays.
1201 */
1202 XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; 1163 XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
1203 TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; 1164 TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
1204 if(sdtClass.arrayOfType == null) 1165 if(sdtClass.arrayOfType == null)
1205 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); 1166 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
1206 1167
1207 /* 1168 // Copy from the immutable array to the mutable array.
1208 * Copy from the immutable array to the mutable array. 1169 // Strip off any LSL wrappers as the script code doesn't expect any.
1209 * Strip off any LSL wrappers as the script code doesn't expect any.
1210 */
1211 object[] srcarr = srclist.Data; 1170 object[] srcarr = srclist.Data;
1212 Array dstarr = (Array)dstarray.instVars.iarObjects[0]; 1171 Array dstarr = (Array)dstarray.instVars.iarObjects[0];
1213 1172
@@ -1233,18 +1192,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1233 */ 1192 */
1234 public static string xmrChars2String(object srcar, int start, int count) 1193 public static string xmrChars2String(object srcar, int start, int count)
1235 { 1194 {
1236 /* 1195 // Make sure they gave us a script-defined array object.
1237 * Make sure they gave us a script-defined array object.
1238 */
1239 XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; 1196 XMRSDTypeClObj array = (XMRSDTypeClObj)srcar;
1240 TokenDeclSDTypeClass sdtClass = array.sdtcClass; 1197 TokenDeclSDTypeClass sdtClass = array.sdtcClass;
1241 if(sdtClass.arrayOfRank == 0) 1198 if(sdtClass.arrayOfRank == 0)
1242 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); 1199 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
1243 1200
1244 /* 1201 // We get a type cast error from mono if they didn't give us a character array.
1245 * We get a type cast error from mono if they didn't give us a character array. 1202 // But if it is ok, create a string from the requested characters.
1246 * But if it is ok, create a string from the requested characters.
1247 */
1248 char[] srcarray = (char[])array.instVars.iarObjects[0]; 1203 char[] srcarray = (char[])array.instVars.iarObjects[0];
1249 return new string(srcarray, start, count); 1204 return new string(srcarray, start, count);
1250 } 1205 }
@@ -1259,18 +1214,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1259 */ 1214 */
1260 public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count) 1215 public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count)
1261 { 1216 {
1262 /* 1217 // Make sure they gave us a script-defined array object.
1263 * Make sure they gave us a script-defined array object.
1264 */
1265 XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; 1218 XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj;
1266 TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; 1219 TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass;
1267 if(sdtClass.arrayOfType == null) 1220 if(sdtClass.arrayOfType == null)
1268 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); 1221 throw new InvalidCastException("only do arrays not " + sdtClass.longName.val);
1269 1222
1270 /* 1223 // We get a type cast error from mono if they didn't give us a character array.
1271 * We get a type cast error from mono if they didn't give us a character array. 1224 // But if it is ok, copy from the string to the character array.
1272 * But if it is ok, copy from the string to the character array.
1273 */
1274 char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; 1225 char[] dstarr = (char[])dstarray.instVars.iarObjects[0];
1275 for(int i = 0; i < count; i++) 1226 for(int i = 0; i < count; i++)
1276 dstarr[i + dststart] = srcstr[i + srcstart]; 1227 dstarr[i + dststart] = srcstr[i + srcstart];
@@ -1343,12 +1294,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1343 1294
1344 // '"'<string>'"' 1295 // '"'<string>'"'
1345 case '"': 1296 case '"':
1346 { 1297 {
1347 --idx; 1298 --idx;
1348 string val = ParseJSONString(json, ref idx); 1299 string val = ParseJSONString(json, ref idx);
1349 dict.SetByKey(keys, val); 1300 dict.SetByKey(keys, val);
1350 break; 1301 break;
1351 } 1302 }
1352 // true false null 1303 // true false null
1353 case 't': 1304 case 't':
1354 if(json.Substring(idx, 3) != "rue") 1305 if(json.Substring(idx, 3) != "rue")
@@ -1373,12 +1324,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1373 1324
1374 // otherwise assume it's a number 1325 // otherwise assume it's a number
1375 default: 1326 default:
1376 { 1327 {
1377 --idx; 1328 --idx;
1378 object val = ParseJSONNumber(json, ref idx); 1329 object val = ParseJSONNumber(json, ref idx);
1379 dict.SetByKey(keys, val); 1330 dict.SetByKey(keys, val);
1380 break; 1331 break;
1381 } 1332 }
1382 } 1333 }
1383 return idx; 1334 return idx;
1384 } 1335 }
@@ -1805,9 +1756,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1805 { 1756 {
1806 BinaryWriter mow = this.migrateOutWriter; 1757 BinaryWriter mow = this.migrateOutWriter;
1807 1758
1808 /* 1759 // Value types (including nulls) are always output directly.
1809 * Value types (including nulls) are always output directly.
1810 */
1811 if(graph == null) 1760 if(graph == null)
1812 { 1761 {
1813 mow.Write((byte)Ser.NULL); 1762 mow.Write((byte)Ser.NULL);
@@ -1893,20 +1842,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1893 return; 1842 return;
1894 } 1843 }
1895 1844
1896 /* 1845 // Script instance pointer is always just that.
1897 * Script instance pointer is always just that.
1898 */
1899 if(graph == this) 1846 if(graph == this)
1900 { 1847 {
1901 mow.Write((byte)Ser.XMRINST); 1848 mow.Write((byte)Ser.XMRINST);
1902 return; 1849 return;
1903 } 1850 }
1904 1851
1905 /* 1852 // Convert lists to object type.
1906 * Convert lists to object type. 1853 // This is compatible with old migration data and also
1907 * This is compatible with old migration data and also 1854 // two vars pointing to same list won't duplicate it.
1908 * two vars pointing to same list won't duplicate it.
1909 */
1910 if(graph is LSL_List) 1855 if(graph is LSL_List)
1911 { 1856 {
1912 object[] data = ((LSL_List)graph).Data; 1857 object[] data = ((LSL_List)graph).Data;
@@ -1920,14 +1865,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1920 graph = oll; 1865 graph = oll;
1921 } 1866 }
1922 1867
1923 /* 1868 // If this same exact object was already serialized,
1924 * If this same exact object was already serialized, 1869 // just output an index telling the receiver to use
1925 * just output an index telling the receiver to use 1870 // that same old object, rather than creating a whole
1926 * that same old object, rather than creating a whole 1871 // new object with the same values. Also this prevents
1927 * new object with the same values. Also this prevents 1872 // self-referencing objects (like arrays) from causing
1928 * self-referencing objects (like arrays) from causing 1873 // an infinite loop.
1929 * an infinite loop.
1930 */
1931 int ident; 1874 int ident;
1932 if(this.migrateOutObjects.TryGetValue(graph, out ident)) 1875 if(this.migrateOutObjects.TryGetValue(graph, out ident))
1933 { 1876 {
@@ -1936,20 +1879,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1936 return; 1879 return;
1937 } 1880 }
1938 1881
1939 /* 1882 // Object not seen before, save its address with an unique
1940 * Object not seen before, save its address with an unique 1883 // ident number that the receiver can easily regenerate.
1941 * ident number that the receiver can easily regenerate.
1942 */
1943 ident = this.migrateOutObjects.Count; 1884 ident = this.migrateOutObjects.Count;
1944 this.migrateOutObjects.Add(graph, ident); 1885 this.migrateOutObjects.Add(graph, ident);
1945 1886
1946 /* 1887 // Now output the object's value(s).
1947 * Now output the object's value(s). 1888 // If the object self-references, the object is alreay entered
1948 * If the object self-references, the object is alreay entered 1889 // in the dictionary and so the self-reference will just emit
1949 * in the dictionary and so the self-reference will just emit 1890 // a DUPREF tag instead of trying to output the whole object
1950 * a DUPREF tag instead of trying to output the whole object 1891 // again.
1951 * again.
1952 */
1953 if(graph is ObjLslList) 1892 if(graph is ObjLslList)
1954 { 1893 {
1955 mow.Write((byte)Ser.LSLLIST); 1894 mow.Write((byte)Ser.LSLLIST);
@@ -2182,43 +2121,43 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2182 return new LSL_Key((string)RecvObjValue()); 2121 return new LSL_Key((string)RecvObjValue());
2183 2122
2184 case Ser.LSLLIST: 2123 case Ser.LSLLIST:
2185 { 2124 {
2186 this.migrateInObjects.Add(ident, null); // placeholder 2125 this.migrateInObjects.Add(ident, null); // placeholder
2187 object[] data = (object[])RecvObjValue(); // read data, maybe using another index 2126 object[] data = (object[])RecvObjValue(); // read data, maybe using another index
2188 LSL_List list = new LSL_List(data); // make LSL-level list 2127 LSL_List list = new LSL_List(data); // make LSL-level list
2189 this.migrateInObjects[ident] = list; // fill in slot 2128 this.migrateInObjects[ident] = list; // fill in slot
2190 return list; 2129 return list;
2191 } 2130 }
2192 2131
2193 case Ser.LSLROT: 2132 case Ser.LSLROT:
2194 { 2133 {
2195 double x = mir.ReadDouble(); 2134 double x = mir.ReadDouble();
2196 double y = mir.ReadDouble(); 2135 double y = mir.ReadDouble();
2197 double z = mir.ReadDouble(); 2136 double z = mir.ReadDouble();
2198 double w = mir.ReadDouble(); 2137 double w = mir.ReadDouble();
2199 return new LSL_Rotation(x, y, z, w); 2138 return new LSL_Rotation(x, y, z, w);
2200 } 2139 }
2201 case Ser.LSLSTR: 2140 case Ser.LSLSTR:
2202 return new LSL_String((string)RecvObjValue()); 2141 return new LSL_String((string)RecvObjValue());
2203 2142
2204 case Ser.LSLVEC: 2143 case Ser.LSLVEC:
2205 { 2144 {
2206 double x = mir.ReadDouble(); 2145 double x = mir.ReadDouble();
2207 double y = mir.ReadDouble(); 2146 double y = mir.ReadDouble();
2208 double z = mir.ReadDouble(); 2147 double z = mir.ReadDouble();
2209 return new LSL_Vector(x, y, z); 2148 return new LSL_Vector(x, y, z);
2210 } 2149 }
2211 2150
2212 case Ser.SYSARRAY: 2151 case Ser.SYSARRAY:
2213 { 2152 {
2214 Type eletype = String2SysType(mir.ReadString()); 2153 Type eletype = String2SysType(mir.ReadString());
2215 int length = mir.ReadInt32(); 2154 int length = mir.ReadInt32();
2216 Array array = Array.CreateInstance(eletype, length); 2155 Array array = Array.CreateInstance(eletype, length);
2217 this.migrateInObjects.Add(ident, array); 2156 this.migrateInObjects.Add(ident, array);
2218 for(int i = 0; i < length; i++) 2157 for(int i = 0; i < length; i++)
2219 array.SetValue(RecvObjValue(), i); 2158 array.SetValue(RecvObjValue(), i);
2220 return array; 2159 return array;
2221 } 2160 }
2222 2161
2223 case Ser.SYSBOOL: 2162 case Ser.SYSBOOL:
2224 return mir.ReadBoolean(); 2163 return mir.ReadBoolean();
@@ -2241,21 +2180,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2241 return s; 2180 return s;
2242 2181
2243 case Ser.XMRARRAY: 2182 case Ser.XMRARRAY:
2244 { 2183 {
2245 XMR_Array array = new XMR_Array(this); 2184 XMR_Array array = new XMR_Array(this);
2246 this.migrateInObjects.Add(ident, array); 2185 this.migrateInObjects.Add(ident, array);
2247 array.RecvArrayObj(this.RecvObjValue); 2186 array.RecvArrayObj(this.RecvObjValue);
2248 return array; 2187 return array;
2249 } 2188 }
2250 2189
2251 case Ser.DUPREF: 2190 case Ser.DUPREF:
2252 { 2191 {
2253 ident = mir.ReadInt32(); 2192 ident = mir.ReadInt32();
2254 object obj = this.migrateInObjects[ident]; 2193 object obj = this.migrateInObjects[ident];
2255 if(obj is ObjLslList) 2194 if(obj is ObjLslList)
2256 obj = new LSL_List(((ObjLslList)obj).objarray); 2195 obj = new LSL_List(((ObjLslList)obj).objarray);
2257 return obj; 2196 return obj;
2258 } 2197 }
2259 2198
2260 case Ser.XMRINST: 2199 case Ser.XMRINST:
2261 return this; 2200 return this;
@@ -2276,29 +2215,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2276 return clobj; 2215 return clobj;
2277 2216
2278 case Ser.SYSERIAL: 2217 case Ser.SYSERIAL:
2279 { 2218 {
2280 int rawLength = mir.ReadInt32(); 2219 int rawLength = mir.ReadInt32();
2281 byte[] rawBytes = mir.ReadBytes(rawLength); 2220 byte[] rawBytes = mir.ReadBytes(rawLength);
2282 MemoryStream memoryStream = new MemoryStream(rawBytes); 2221 MemoryStream memoryStream = new MemoryStream(rawBytes);
2283 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = 2222 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
2284 new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 2223 new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
2285 object graph = bformatter.Deserialize(memoryStream); 2224 object graph = bformatter.Deserialize(memoryStream);
2286 this.migrateInObjects.Add(ident, graph); 2225 this.migrateInObjects.Add(ident, graph);
2287 return graph; 2226 return graph;
2288 } 2227 }
2289 2228
2290 case Ser.THROWNEX: 2229 case Ser.THROWNEX:
2291 { 2230 {
2292 int rawLength = mir.ReadInt32(); 2231 int rawLength = mir.ReadInt32();
2293 byte[] rawBytes = mir.ReadBytes(rawLength); 2232 byte[] rawBytes = mir.ReadBytes(rawLength);
2294 MemoryStream memoryStream = new MemoryStream(rawBytes); 2233 MemoryStream memoryStream = new MemoryStream(rawBytes);
2295 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = 2234 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter =
2296 new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 2235 new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
2297 object graph = bformatter.Deserialize(memoryStream); 2236 object graph = bformatter.Deserialize(memoryStream);
2298 this.migrateInObjects.Add(ident, graph); 2237 this.migrateInObjects.Add(ident, graph);
2299 ((ScriptThrownException)graph).thrown = RecvObjValue(); 2238 ((ScriptThrownException)graph).thrown = RecvObjValue();
2300 return graph; 2239 return graph;
2301 } 2240 }
2302 2241
2303 default: 2242 default:
2304 throw new Exception("bad stream code " + code.ToString()); 2243 throw new Exception("bad stream code " + code.ToString());
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs
index fb5c75e..833211f 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs
@@ -249,22 +249,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
249 { 249 {
250 lock(m_QueueLock) 250 lock(m_QueueLock)
251 { 251 {
252 /* 252 // Say how long to sleep.
253 * Say how long to sleep.
254 */
255 m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms); 253 m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms);
256 254
257 /* 255 // Don't wake on any events.
258 * Don't wake on any events.
259 */
260 m_SleepEventMask1 = 0; 256 m_SleepEventMask1 = 0;
261 m_SleepEventMask2 = 0; 257 m_SleepEventMask2 = 0;
262 } 258 }
263 259
264 /* 260 // The compiler follows all calls to llSleep() with a call to CheckRun().
265 * The compiler follows all calls to llSleep() with a call to CheckRun(). 261 // So tell CheckRun() to suspend the microthread.
266 * So tell CheckRun() to suspend the microthread.
267 */
268 suspendOnCheckRunTemp = true; 262 suspendOnCheckRunTemp = true;
269 } 263 }
270 264
@@ -327,10 +321,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
327 if(callMode == CallMode_NORMAL) 321 if(callMode == CallMode_NORMAL)
328 goto findevent; 322 goto findevent;
329 323
330 /* 324 // Stack frame is being restored as saved via CheckRun...().
331 * Stack frame is being restored as saved via CheckRun...(). 325 // Restore necessary values then jump to __call<n> label to resume processing.
332 * Restore necessary values then jump to __call<n> label to resume processing.
333 */
334 sv = RestoreStackFrame("xmrEventDequeue", out callNo); 326 sv = RestoreStackFrame("xmrEventDequeue", out callNo);
335 sleepUntil = DateTime.Parse((string)sv[0]); 327 sleepUntil = DateTime.Parse((string)sv[0]);
336 returnMask1 = (int)sv[1]; 328 returnMask1 = (int)sv[1];
@@ -353,9 +345,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
353 } 345 }
354 throw new ScriptBadCallNoException(callNo); 346 throw new ScriptBadCallNoException(callNo);
355 347
356 /* 348 // Find first event that matches either the return or background masks.
357 * Find first event that matches either the return or background masks.
358 */
359 findevent: 349 findevent:
360 Monitor.Enter(m_QueueLock); 350 Monitor.Enter(m_QueueLock);
361 for(lln = m_EventQueue.First; lln != null; lln = lln.Next) 351 for(lln = m_EventQueue.First; lln != null; lln = lln.Next)
@@ -369,9 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
369 goto remfromq; 359 goto remfromq;
370 } 360 }
371 361
372 /* 362 // Nothing found, sleep while one comes in.
373 * Nothing found, sleep while one comes in.
374 */
375 m_SleepUntil = sleepUntil; 363 m_SleepUntil = sleepUntil;
376 m_SleepEventMask1 = mask1; 364 m_SleepEventMask1 = mask1;
377 m_SleepEventMask2 = mask2; 365 m_SleepEventMask2 = mask2;
@@ -382,9 +370,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
382 CheckRunQuick(); 370 CheckRunQuick();
383 goto checktmo; 371 goto checktmo;
384 372
385 /* 373 // Found one, remove it from queue.
386 * Found one, remove it from queue.
387 */
388 remfromq: 374 remfromq:
389 m_EventQueue.Remove(lln); 375 m_EventQueue.Remove(lln);
390 if((uint)evc1 < (uint)m_EventCounts.Length) 376 if((uint)evc1 < (uint)m_EventCounts.Length)
@@ -393,16 +379,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
393 Monitor.Exit(m_QueueLock); 379 Monitor.Exit(m_QueueLock);
394 m_InstEHEvent++; 380 m_InstEHEvent++;
395 381
396 /* 382 // See if returnable or background event.
397 * See if returnable or background event.
398 */
399 if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || 383 if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) ||
400 (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) 384 (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0)))
401 { 385 {
402 /* 386 // Returnable event, return its parameters in a list.
403 * Returnable event, return its parameters in a list. 387 // Also set the detect parameters to what the event has.
404 * Also set the detect parameters to what the event has.
405 */
406 int plen = evt.Params.Length; 388 int plen = evt.Params.Length;
407 object[] plist = new object[plen + 1]; 389 object[] plist = new object[plen + 1];
408 plist[0] = (LSL_Integer)evc1; 390 plist[0] = (LSL_Integer)evc1;
@@ -421,10 +403,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
421 return new LSL_List(plist); 403 return new LSL_List(plist);
422 } 404 }
423 405
424 /* 406 // It is a background event, simply call its event handler,
425 * It is a background event, simply call its event handler, 407 // then check event queue again.
426 * then check event queue again.
427 */
428 callNo = 1; 408 callNo = 1;
429 __call1: 409 __call1:
430 ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1]; 410 ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1];
@@ -450,28 +430,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
450 this.eventCode = saveEventCode; 430 this.eventCode = saveEventCode;
451 } 431 }
452 432
453 /* 433 // Keep waiting until we find a returnable event or timeout.
454 * Keep waiting until we find a returnable event or timeout.
455 */
456 checktmo: 434 checktmo:
457 if(DateTime.UtcNow < sleepUntil) 435 if(DateTime.UtcNow < sleepUntil)
458 goto findevent; 436 goto findevent;
459 437
460 /* 438 // We timed out, return an empty list.
461 * We timed out, return an empty list.
462 */
463 return emptyList; 439 return emptyList;
464 } 440 }
465 finally 441 finally
466 { 442 {
467 if(callMode != CallMode_NORMAL) 443 if(callMode != CallMode_NORMAL)
468 { 444 {
469 445 // Stack frame is being saved by CheckRun...().
470 /* 446 // Save everything we need at the __call<n> labels so we can restore it
471 * Stack frame is being saved by CheckRun...(). 447 // when we need to.
472 * Save everything we need at the __call<n> labels so we can restore it
473 * when we need to.
474 */
475 sv = CaptureStackFrame("xmrEventDequeue", callNo, 9); 448 sv = CaptureStackFrame("xmrEventDequeue", callNo, 9);
476 sv[0] = sleepUntil.ToString(); // needed at __call0,__call1 449 sv[0] = sleepUntil.ToString(); // needed at __call0,__call1
477 sv[1] = returnMask1; // needed at __call0,__call1 450 sv[1] = returnMask1; // needed at __call0,__call1
@@ -606,22 +579,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
606 */ 579 */
607 public override void StateChange() 580 public override void StateChange()
608 { 581 {
609 /* 582 // Cancel any llListen()s etc.
610 * Cancel any llListen()s etc. 583 // But llSetTimerEvent() should persist.
611 * But llSetTimerEvent() should persist.
612 */
613 object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID); 584 object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID);
614 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 585 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
615 m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers); 586 m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers);
616 587
617 /* 588 // Tell whoever cares which event handlers the new state has.
618 * Tell whoever cares which event handlers the new state has.
619 */
620 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); 589 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode));
621 590
622 /* 591 // Clear out any old events from the queue.
623 * Clear out any old events from the queue.
624 */
625 lock(m_QueueLock) 592 lock(m_QueueLock)
626 { 593 {
627 m_EventQueue.Clear(); 594 m_EventQueue.Clear();
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs
index 68ec322..85867ab 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs
@@ -390,9 +390,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
390 LoadScriptState(doc); 390 LoadScriptState(doc);
391 } 391 }
392 392
393 /* 393 // Post event(s) saying what caused the script to start.
394 * Post event(s) saying what caused the script to start.
395 */
396 if(m_PostOnRez) 394 if(m_PostOnRez)
397 { 395 {
398 PostEvent(new EventParams("on_rez", 396 PostEvent(new EventParams("on_rez",
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
index 8f020ce..0af3d37 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
@@ -74,14 +74,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
74 */ 74 */
75 public void Dispose() 75 public void Dispose()
76 { 76 {
77 /* 77 // Tell script stop executing next time it calls CheckRun().
78 * Tell script stop executing next time it calls CheckRun().
79 */
80 suspendOnCheckRunHold = true; 78 suspendOnCheckRunHold = true;
81 79
82 /* 80 // Don't send us any more events.
83 * Don't send us any more events.
84 */
85 lock(m_RunLock) 81 lock(m_RunLock)
86 { 82 {
87 if(m_Part != null) 83 if(m_Part != null)
@@ -92,10 +88,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
92 } 88 }
93 } 89 }
94 90
95 /* 91 // Let script methods get garbage collected if no one else is using
96 * Let script methods get garbage collected if no one else is using 92 // them.
97 * them.
98 */
99 DecObjCodeRefCount(); 93 DecObjCodeRefCount();
100 } 94 }
101 95
@@ -244,26 +238,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
244 238
245 public static string GetScriptFileName(string scriptBasePath, string filename) 239 public static string GetScriptFileName(string scriptBasePath, string filename)
246 { 240 {
247 /* 241 // Get old path, ie, all files lumped in a single huge directory.
248 * Get old path, ie, all files lumped in a single huge directory.
249 */
250 string oldPath = Path.Combine(scriptBasePath, filename); 242 string oldPath = Path.Combine(scriptBasePath, filename);
251 243
252 /* 244 // Get new path, ie, files split up based on first 2 chars of name.
253 * Get new path, ie, files split up based on first 2 chars of name. 245 // string subdir = filename.Substring (0, 2);
254 */ 246 // filename = filename.Substring (2);
255 // string subdir = filename.Substring (0, 2);
256 // filename = filename.Substring (2);
257 string subdir = filename.Substring(0, 1); 247 string subdir = filename.Substring(0, 1);
258 filename = filename.Substring(1); 248 filename = filename.Substring(1);
259 scriptBasePath = Path.Combine(scriptBasePath, subdir); 249 scriptBasePath = Path.Combine(scriptBasePath, subdir);
260 Directory.CreateDirectory(scriptBasePath); 250 Directory.CreateDirectory(scriptBasePath);
261 string newPath = Path.Combine(scriptBasePath, filename); 251 string newPath = Path.Combine(scriptBasePath, filename);
262 252
263 /* 253 // If file exists only in old location, move to new location.
264 * If file exists only in old location, move to new location. 254 // If file exists in both locations, delete old location.
265 * If file exists in both locations, delete old location.
266 */
267 if(File.Exists(oldPath)) 255 if(File.Exists(oldPath))
268 { 256 {
269 if(File.Exists(newPath)) 257 if(File.Exists(newPath))
@@ -276,9 +264,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
276 } 264 }
277 } 265 }
278 266
279 /* 267 // Always return new location.
280 * Always return new location.
281 */
282 return newPath; 268 return newPath;
283 } 269 }
284 270
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
index 8603fbf..8ac9794 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
@@ -66,36 +66,27 @@ namespace OpenSim.Region.ScriptEngine.Yengine
66 ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), 66 ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
67 evt.EventName); 67 evt.EventName);
68 68
69 /* 69 // Put event on end of event queue.
70 * Put event on end of event queue.
71 */
72 bool startIt = false; 70 bool startIt = false;
73 bool wakeIt = false; 71 bool wakeIt = false;
74 lock(m_QueueLock) 72 lock(m_QueueLock)
75 { 73 {
76 bool construct = (m_IState == XMRInstState.CONSTRUCT); 74 bool construct = (m_IState == XMRInstState.CONSTRUCT);
77 75
78 /* 76 // Ignore event if we don't even have such an handler in any state.
79 * Ignore event if we don't even have such an handler in any state. 77 // We can't be state-specific here because state might be different
80 * We can't be state-specific here because state might be different 78 // by the time this event is dequeued and delivered to the script.
81 * by the time this event is dequeued and delivered to the script.
82 */
83 if(!construct && // make sure m_HaveEventHandlers is filled in 79 if(!construct && // make sure m_HaveEventHandlers is filled in
84 ((uint)evc < (uint)m_HaveEventHandlers.Length) && 80 ((uint)evc < (uint)m_HaveEventHandlers.Length) &&
85 !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state 81 !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
86 return; 82 return;
87 83
88 84 // Not running means we ignore any incoming events.
89 /* 85 // But queue if still constructing because m_Running is not yet valid.
90 * Not running means we ignore any incoming events.
91 * But queue if still constructing because m_Running is not yet valid.
92 */
93 if(!m_Running && !construct) 86 if(!m_Running && !construct)
94 return; 87 return;
95 88
96 /* 89 // Only so many of each event type allowed to queue.
97 * Only so many of each event type allowed to queue.
98 */
99 if((uint)evc < (uint)m_EventCounts.Length) 90 if((uint)evc < (uint)m_EventCounts.Length)
100 { 91 {
101 if(evc == ScriptEventCode.timer) 92 if(evc == ScriptEventCode.timer)
@@ -109,29 +100,23 @@ namespace OpenSim.Region.ScriptEngine.Yengine
109 m_EventCounts[(int)evc]++; 100 m_EventCounts[(int)evc]++;
110 } 101 }
111 102
112 /* 103 // Put event on end of instance's event queue.
113 * Put event on end of instance's event queue.
114 */
115 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt); 104 LinkedListNode<EventParams> lln = new LinkedListNode<EventParams>(evt);
116 switch(evc) 105 switch(evc)
117 { 106 {
118 /* 107 // These need to go first. The only time we manually
119 * These need to go first. The only time we manually 108 // queue them is for the default state_entry() and we
120 * queue them is for the default state_entry() and we 109 // need to make sure they go before any attach() events
121 * need to make sure they go before any attach() events 110 // so the heapLimit value gets properly initialized.
122 * so the heapLimit value gets properly initialized.
123 */
124 case ScriptEventCode.state_entry: 111 case ScriptEventCode.state_entry:
125 m_EventQueue.AddFirst(lln); 112 m_EventQueue.AddFirst(lln);
126 break; 113 break;
127 114
128 /* 115 // The attach event sneaks to the front of the queue.
129 * The attach event sneaks to the front of the queue. 116 // This is needed for quantum limiting to work because
130 * This is needed for quantum limiting to work because 117 // we want the attach(NULL_KEY) event to come in front
131 * we want the attach(NULL_KEY) event to come in front 118 // of all others so the m_DetachQuantum won't run out
132 * of all others so the m_DetachQuantum won't run out 119 // before attach(NULL_KEY) is executed.
133 * before attach(NULL_KEY) is executed.
134 */
135 case ScriptEventCode.attach: 120 case ScriptEventCode.attach:
136 if(evt.Params[0].ToString() == UUID.Zero.ToString()) 121 if(evt.Params[0].ToString() == UUID.Zero.ToString())
137 { 122 {
@@ -150,11 +135,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
150 else 135 else
151 m_EventQueue.AddBefore(lln2, lln); 136 m_EventQueue.AddBefore(lln2, lln);
152 137
153 /* If we're detaching, limit the qantum. This will also 138 // If we're detaching, limit the qantum. This will also
154 * cause the script to self-suspend after running this 139 // cause the script to self-suspend after running this
155 * event 140 // event
156 */
157
158 m_DetachReady.Reset(); 141 m_DetachReady.Reset();
159 m_DetachQuantum = 100; 142 m_DetachQuantum = 100;
160 } 143 }
@@ -163,31 +146,25 @@ namespace OpenSim.Region.ScriptEngine.Yengine
163 146
164 break; 147 break;
165 148
166 /* 149 // All others just go on end in the order queued.
167 * All others just go on end in the order queued.
168 */
169 default: 150 default:
170 m_EventQueue.AddLast(lln); 151 m_EventQueue.AddLast(lln);
171 break; 152 break;
172 } 153 }
173 154
174 /* 155 // If instance is idle (ie, not running or waiting to run),
175 * If instance is idle (ie, not running or waiting to run), 156 // flag it to be on m_StartQueue as we are about to do so.
176 * flag it to be on m_StartQueue as we are about to do so. 157 // Flag it now before unlocking so another thread won't try
177 * Flag it now before unlocking so another thread won't try 158 // to do the same thing right now.
178 * to do the same thing right now. 159 // Dont' flag it if it's still suspended!
179 * Dont' flag it if it's still suspended!
180 */
181 if((m_IState == XMRInstState.IDLE) && !m_Suspended) 160 if((m_IState == XMRInstState.IDLE) && !m_Suspended)
182 { 161 {
183 m_IState = XMRInstState.ONSTARTQ; 162 m_IState = XMRInstState.ONSTARTQ;
184 startIt = true; 163 startIt = true;
185 } 164 }
186 165
187 /* 166 // If instance is sleeping (ie, possibly in xmrEventDequeue),
188 * If instance is sleeping (ie, possibly in xmrEventDequeue), 167 // wake it up if event is in the mask.
189 * wake it up if event is in the mask.
190 */
191 if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) 168 if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended)
192 { 169 {
193 int evc1 = (int)evc; 170 int evc1 = (int)evc;
@@ -198,16 +175,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
198 } 175 }
199 } 176 }
200 177
201 /* 178 // If transitioned from IDLE->ONSTARTQ, actually go insert it
202 * If transitioned from IDLE->ONSTARTQ, actually go insert it 179 // on m_StartQueue and give the RunScriptThread() a wake-up.
203 * on m_StartQueue and give the RunScriptThread() a wake-up.
204 */
205 if(startIt) 180 if(startIt)
206 m_Engine.QueueToStart(this); 181 m_Engine.QueueToStart(this);
207 182
208 /* 183 // Likewise, if the event mask triggered a wake, wake it up.
209 * Likewise, if the event mask triggered a wake, wake it up.
210 */
211 if(wakeIt) 184 if(wakeIt)
212 { 185 {
213 m_SleepUntil = DateTime.MinValue; 186 m_SleepUntil = DateTime.MinValue;
@@ -215,20 +188,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
215 } 188 }
216 } 189 }
217 190
218 /* 191 // This is called in the script thread to step script until it calls
219 * This is called in the script thread to step script until it calls 192 // CheckRun(). It returns what the instance's next state should be,
220 * CheckRun(). It returns what the instance's next state should be, 193 // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
221 * ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.
222 */
223 public XMRInstState RunOne() 194 public XMRInstState RunOne()
224 { 195 {
225 DateTime now = DateTime.UtcNow; 196 DateTime now = DateTime.UtcNow;
226 m_SliceStart = Util.GetTimeStampMS(); 197 m_SliceStart = Util.GetTimeStampMS();
227 198
228 /* 199 // If script has called llSleep(), don't do any more until time is up.
229 * If script has called llSleep(), don't do any more until time is
230 * up.
231 */
232 m_RunOnePhase = "check m_SleepUntil"; 200 m_RunOnePhase = "check m_SleepUntil";
233 if(m_SleepUntil > now) 201 if(m_SleepUntil > now)
234 { 202 {
@@ -236,9 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
236 return XMRInstState.ONSLEEPQ; 204 return XMRInstState.ONSLEEPQ;
237 } 205 }
238 206
239 /* 207 // Also, someone may have called Suspend().
240 * Also, someone may have called Suspend().
241 */
242 m_RunOnePhase = "check m_SuspendCount"; 208 m_RunOnePhase = "check m_SuspendCount";
243 if(m_SuspendCount > 0) 209 if(m_SuspendCount > 0)
244 { 210 {
@@ -246,11 +212,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
246 return XMRInstState.SUSPENDED; 212 return XMRInstState.SUSPENDED;
247 } 213 }
248 214
249 /* 215 // Make sure we aren't being migrated in or out and prevent that
250 * Make sure we aren't being migrated in or out and prevent that 216 // whilst we are in here. If migration has it locked, don't call
251 * whilst we are in here. If migration has it locked, don't call 217 // back right away, delay a bit so we don't get in infinite loop.
252 * back right away, delay a bit so we don't get in infinite loop.
253 */
254 m_RunOnePhase = "lock m_RunLock"; 218 m_RunOnePhase = "lock m_RunLock";
255 if(!Monitor.TryEnter(m_RunLock)) 219 if(!Monitor.TryEnter(m_RunLock))
256 { 220 {
@@ -264,18 +228,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
264 CheckRunLockInvariants(true); 228 CheckRunLockInvariants(true);
265 Exception e = null; 229 Exception e = null;
266 230
267 /* 231 // Maybe it has been Disposed()
268 * Maybe it has been Disposed()
269 */
270 if(m_Part == null) 232 if(m_Part == null)
271 { 233 {
272 m_RunOnePhase = "runone saw it disposed"; 234 m_RunOnePhase = "runone saw it disposed";
273 return XMRInstState.DISPOSED; 235 return XMRInstState.DISPOSED;
274 } 236 }
275 237
276 /* 238 // Do some more of the last event if it didn't finish.
277 * Do some more of the last event if it didn't finish.
278 */
279 if(this.eventCode != ScriptEventCode.None) 239 if(this.eventCode != ScriptEventCode.None)
280 { 240 {
281 lock(m_QueueLock) 241 lock(m_QueueLock)
@@ -297,10 +257,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
297 e = ResumeEx(); 257 e = ResumeEx();
298 } 258 }
299 259
300 /* 260 // Otherwise, maybe we can dequeue a new event and start
301 * Otherwise, maybe we can dequeue a new event and start 261 // processing it.
302 * processing it.
303 */
304 else 262 else
305 { 263 {
306 m_RunOnePhase = "lock event queue"; 264 m_RunOnePhase = "lock event queue";
@@ -310,14 +268,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
310 lock(m_QueueLock) 268 lock(m_QueueLock)
311 { 269 {
312 270
313 /* We can't get here unless the script has been resumed 271 // We can't get here unless the script has been resumed
314 * after creation, then suspended again, and then had 272 // after creation, then suspended again, and then had
315 * an event posted to it. We just pretend there is no 273 // an event posted to it. We just pretend there is no
316 * event int he queue and let the normal mechanics 274 // event int he queue and let the normal mechanics
317 * carry out the suspension. A Resume will handle the 275 // carry out the suspension. A Resume will handle the
318 * restarting gracefully. This is taking the easy way 276 // restarting gracefully. This is taking the easy way
319 * out and may be improved in the future. 277 // out and may be improved in the future.
320 */
321 278
322 if(m_Suspended) 279 if(m_Suspended)
323 { 280 {
@@ -336,11 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
336 evt.EventName); 293 evt.EventName);
337 if(evc != ScriptEventCode.attach) 294 if(evc != ScriptEventCode.attach)
338 { 295 {
339 /* 296 // This is the case where the attach event
340 * This is the case where the attach event 297 // has completed and another event is queued
341 * has completed and another event is queued 298 // Stop it from running and suspend
342 * Stop it from running and suspend
343 */
344 m_Suspended = true; 299 m_Suspended = true;
345 m_DetachReady.Set(); 300 m_DetachReady.Set();
346 m_DetachQuantum = 0; 301 m_DetachQuantum = 0;
@@ -356,18 +311,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
356 m_EventCounts[(int)evc]--; 311 m_EventCounts[(int)evc]--;
357 } 312 }
358 313
359 /* 314 // If there is no event to dequeue, don't run this script
360 * If there is no event to dequeue, don't run this script 315 // until another event gets queued.
361 * until another event gets queued.
362 */
363 if(evt == null) 316 if(evt == null)
364 { 317 {
365 if(m_DetachQuantum > 0) 318 if(m_DetachQuantum > 0)
366 { 319 {
367 /* 320 // This will happen if the attach event has run
368 * This will happen if the attach event has run 321 // and exited with time slice left.
369 * and exited with time slice left.
370 */
371 m_Suspended = true; 322 m_Suspended = true;
372 m_DetachReady.Set(); 323 m_DetachReady.Set();
373 m_DetachQuantum = 0; 324 m_DetachQuantum = 0;
@@ -378,10 +329,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
378 } 329 }
379 } 330 }
380 331
381 /* 332 // Dequeued an event, so start it going until it either
382 * Dequeued an event, so start it going until it either 333 // finishes or it calls CheckRun().
383 * finishes or it calls CheckRun().
384 */
385 m_RunOnePhase = "start event handler"; 334 m_RunOnePhase = "start event handler";
386 m_DetectParams = evt.DetectParams; 335 m_DetectParams = evt.DetectParams;
387 m_LastRanAt = now; 336 m_LastRanAt = now;
@@ -391,9 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
391 m_RunOnePhase = "done running"; 340 m_RunOnePhase = "done running";
392 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; 341 m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds;
393 342
394 /* 343 // Maybe it puqued.
395 * Maybe it puqued.
396 */
397 if(e != null) 344 if(e != null)
398 { 345 {
399 m_RunOnePhase = "handling exception " + e.Message; 346 m_RunOnePhase = "handling exception " + e.Message;
@@ -403,9 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
403 return XMRInstState.FINISHED; 350 return XMRInstState.FINISHED;
404 } 351 }
405 352
406 /* 353 // If event handler completed, get rid of detect params.
407 * If event handler completed, get rid of detect params.
408 */
409 if(this.eventCode == ScriptEventCode.None) 354 if(this.eventCode == ScriptEventCode.None)
410 m_DetectParams = null; 355 m_DetectParams = null;
411 356
@@ -417,9 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
417 Monitor.Exit(m_RunLock); 362 Monitor.Exit(m_RunLock);
418 } 363 }
419 364
420 /* 365 // Cycle script through the yield queue and call it back asap.
421 * Cycle script through the yield queue and call it back asap.
422 */
423 m_RunOnePhase = "last return"; 366 m_RunOnePhase = "last return";
424 return XMRInstState.ONYIELDQ; 367 return XMRInstState.ONYIELDQ;
425 } 368 }
@@ -433,10 +376,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
433 376
434 public void CheckRunLockInvariants(bool throwIt) 377 public void CheckRunLockInvariants(bool throwIt)
435 { 378 {
436 /* 379 // If not executing any event handler, there shouldn't be any saved stack frames.
437 * If not executing any event handler, there shouldn't be any saved stack frames. 380 // If executing an event handler, there should be some saved stack frames.
438 * If executing an event handler, there should be some saved stack frames.
439 */
440 bool active = (stackFrames != null); 381 bool active = (stackFrames != null);
441 ScriptEventCode ec = this.eventCode; 382 ScriptEventCode ec = this.eventCode;
442 if(((ec == ScriptEventCode.None) && active) || 383 if(((ec == ScriptEventCode.None) && active) ||
@@ -470,88 +411,67 @@ namespace OpenSim.Region.ScriptEngine.Yengine
470 */ 411 */
471 private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs) 412 private Exception StartEventHandler(ScriptEventCode eventCode, object[] ehArgs)
472 { 413 {
473 /* 414 // We use this.eventCode == ScriptEventCode.None to indicate we are idle.
474 * We use this.eventCode == ScriptEventCode.None to indicate we are idle. 415 // So trying to execute ScriptEventCode.None might make a mess.
475 * So trying to execute ScriptEventCode.None might make a mess.
476 */
477 if(eventCode == ScriptEventCode.None) 416 if(eventCode == ScriptEventCode.None)
478 return new Exception("Can't process ScriptEventCode.None"); 417 return new Exception("Can't process ScriptEventCode.None");
479 418
480 /* 419 // Silly to even try if there is no handler defined for this event.
481 * Silly to even try if there is no handler defined for this event.
482 */
483 if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null)) 420 if(((int)eventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)eventCode] == null))
484 return null; 421 return null;
485 422
486 /* 423 // The microthread shouldn't be processing any event code.
487 * The microthread shouldn't be processing any event code. 424 // These are assert checks so we throw them directly as exceptions.
488 * These are assert checks so we throw them directly as exceptions.
489 */
490 if(this.eventCode != ScriptEventCode.None) 425 if(this.eventCode != ScriptEventCode.None)
491 throw new Exception("still processing event " + this.eventCode.ToString()); 426 throw new Exception("still processing event " + this.eventCode.ToString());
492 427
493 /* 428 // Save eventCode so we know what event handler to run in the microthread.
494 * Save eventCode so we know what event handler to run in the microthread. 429 // And it also marks us busy so we can't be started again and this event lost.
495 * And it also marks us busy so we can't be started again and this event lost.
496 */
497 this.eventCode = eventCode; 430 this.eventCode = eventCode;
498 this.ehArgs = ehArgs; 431 this.ehArgs = ehArgs;
499 432
500 /* 433 // This calls ScriptUThread.Main() directly, and returns when Main() [indirectly]
501 * This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] 434 // calls Suspend() or when Main() returns, whichever occurs first.
502 * calls Suspend() or when Main() returns, whichever occurs first. 435 // Setting stackFrames = null means run the event handler from the beginning
503 * Setting stackFrames = null means run the event handler from the beginning 436 // without doing any stack frame restores first.
504 * without doing any stack frame restores first.
505 */
506 this.stackFrames = null; 437 this.stackFrames = null;
507 return StartEx(); 438 return StartEx();
508 } 439 }
509 440
510
511 /** 441 /**
512 * @brief There was an exception whilst starting/running a script event handler. 442 * @brief There was an exception whilst starting/running a script event handler.
513 * Maybe we handle it directly or just print an error message. 443 * Maybe we handle it directly or just print an error message.
514 */ 444 */
515 private void HandleScriptException(Exception e) 445 private void HandleScriptException(Exception e)
516 { 446 {
517 /* 447 // The script threw some kind of exception that was not caught at
518 * The script threw some kind of exception that was not caught at 448 // script level, so the script is no longer running an event handler.
519 * script level, so the script is no longer running an event handler.
520 */
521 eventCode = ScriptEventCode.None; 449 eventCode = ScriptEventCode.None;
522 450
523 if(e is ScriptDeleteException) 451 if(e is ScriptDeleteException)
524 { 452 {
525 /* 453 // Script did something like llRemoveInventory(llGetScriptName());
526 * Script did something like llRemoveInventory(llGetScriptName()); 454 // ... to delete itself from the object.
527 * ... to delete itself from the object.
528 */
529 m_SleepUntil = DateTime.MaxValue; 455 m_SleepUntil = DateTime.MaxValue;
530 Verbose("[YEngine]: script self-delete {0}", m_ItemID); 456 Verbose("[YEngine]: script self-delete {0}", m_ItemID);
531 m_Part.Inventory.RemoveInventoryItem(m_ItemID); 457 m_Part.Inventory.RemoveInventoryItem(m_ItemID);
532 } 458 }
533 else if(e is ScriptDieException) 459 else if(e is ScriptDieException)
534 { 460 {
535 /* 461 // Script did an llDie()
536 * Script did an llDie()
537 */
538 m_RunOnePhase = "dying..."; 462 m_RunOnePhase = "dying...";
539 m_SleepUntil = DateTime.MaxValue; 463 m_SleepUntil = DateTime.MaxValue;
540 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); 464 m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false);
541 } 465 }
542 else if(e is ScriptResetException) 466 else if(e is ScriptResetException)
543 { 467 {
544 /* 468 // Script did an llResetScript().
545 * Script did an llResetScript().
546 */
547 m_RunOnePhase = "resetting..."; 469 m_RunOnePhase = "resetting...";
548 ResetLocked("HandleScriptResetException"); 470 ResetLocked("HandleScriptResetException");
549 } 471 }
550 else 472 else
551 { 473 {
552 /* 474 // Some general script error.
553 * Some general script error.
554 */
555 SendErrorMessage(e); 475 SendErrorMessage(e);
556 } 476 }
557 return; 477 return;
@@ -570,16 +490,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
570 msg.Append(m_ItemID); 490 msg.Append(m_ItemID);
571 msg.Append('\n'); 491 msg.Append('\n');
572 492
573 /* 493 // Add exception message.
574 * Add exception message.
575 */
576 string des = e.Message; 494 string des = e.Message;
577 des = (des == null) ? "" : (": " + des); 495 des = (des == null) ? "" : (": " + des);
578 msg.Append(e.GetType().Name + des + "\n"); 496 msg.Append(e.GetType().Name + des + "\n");
579 497
580 /* 498 // Tell script owner what to do.
581 * Tell script owner what to do.
582 */
583 msg.Append("Prim: <"); 499 msg.Append("Prim: <");
584 msg.Append(m_Part.Name); 500 msg.Append(m_Part.Name);
585 msg.Append(">, Script: <"); 501 msg.Append(">, Script: <");
@@ -595,20 +511,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
595 msg.Append((int)Math.Floor(pos.Z)); 511 msg.Append((int)Math.Floor(pos.Z));
596 msg.Append(">\nScript must be Reset to re-enable.\n"); 512 msg.Append(">\nScript must be Reset to re-enable.\n");
597 513
598 /* 514 // Display full exception message in log.
599 * Display full exception message in log.
600 */
601 m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); 515 m_log.Info(msg.ToString() + XMRExceptionStackString(e), e);
602 516
603 /* 517 // Give script owner the stack dump.
604 * Give script owner the stack dump.
605 */
606 msg.Append(XMRExceptionStackString(e)); 518 msg.Append(XMRExceptionStackString(e));
607 519
608 /* 520 // Send error message to owner.
609 * Send error message to owner. 521 // Suppress internal code stack trace lines.
610 * Suppress internal code stack trace lines.
611 */
612 string msgst = msg.ToString(); 522 string msgst = msg.ToString();
613 if(!msgst.EndsWith("\n")) 523 if(!msgst.EndsWith("\n"))
614 msgst += '\n'; 524 msgst += '\n';
@@ -630,10 +540,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
630 imstr.Append('\n'); 540 imstr.Append('\n');
631 } 541 }
632 542
633 /* 543 // Send as instant message in case user not online.
634 * Send as instant message in case user not online. 544 // Code modelled from llInstantMessage().
635 * Code modelled from llInstantMessage().
636 */
637 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>(); 545 IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface<IMessageTransferModule>();
638 if(transferModule != null) 546 if(transferModule != null)
639 { 547 {
@@ -661,10 +569,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
661 }); 569 });
662 } 570 }
663 571
664 /* 572 // Say script is sleeping for a very long time.
665 * Say script is sleeping for a very long time. 573 // Reset() is able to cancel this sleeping.
666 * Reset() is able to cancel this sleeping.
667 */
668 m_SleepUntil = DateTime.MaxValue; 574 m_SleepUntil = DateTime.MaxValue;
669 } 575 }
670 576
@@ -678,18 +584,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
678 XMRInstState iState = m_IState; 584 XMRInstState iState = m_IState;
679 switch(iState) 585 switch(iState)
680 { 586 {
681 /* 587 // If it's really being constructed now, that's about as reset as we get.
682 * If it's really being constructed now, that's about as reset as we get.
683 */
684 case XMRInstState.CONSTRUCT: 588 case XMRInstState.CONSTRUCT:
685 return; 589 return;
686 590
687 /* 591 // If it's idle, that means it is ready to receive a new event.
688 * If it's idle, that means it is ready to receive a new event. 592 // So we lock the event queue to prevent another thread from taking
689 * So we lock the event queue to prevent another thread from taking 593 // it out of idle, verify that it is still in idle then transition
690 * it out of idle, verify that it is still in idle then transition 594 // it to resetting so no other thread will touch it.
691 * it to resetting so no other thread will touch it.
692 */
693 case XMRInstState.IDLE: 595 case XMRInstState.IDLE:
694 lock(m_QueueLock) 596 lock(m_QueueLock)
695 { 597 {
@@ -701,12 +603,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
701 } 603 }
702 goto checkstate; 604 goto checkstate;
703 605
704 /* 606 // If it's on the start queue, that means it is about to dequeue an
705 * If it's on the start queue, that means it is about to dequeue an 607 // event and start processing it. So we lock the start queue so it
706 * event and start processing it. So we lock the start queue so it 608 // can't be started and transition it to resetting so no other thread
707 * can't be started and transition it to resetting so no other thread 609 // will touch it.
708 * will touch it.
709 */
710 case XMRInstState.ONSTARTQ: 610 case XMRInstState.ONSTARTQ:
711 lock(m_Engine.m_StartQueue) 611 lock(m_Engine.m_StartQueue)
712 { 612 {
@@ -719,10 +619,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
719 } 619 }
720 goto checkstate; 620 goto checkstate;
721 621
722 /* 622 // If it's running, tell CheckRun() to suspend the thread then go back
723 * If it's running, tell CheckRun() to suspend the thread then go back 623 // to see what it got transitioned to.
724 * to see what it got transitioned to.
725 */
726 case XMRInstState.RUNNING: 624 case XMRInstState.RUNNING:
727 suspendOnCheckRunHold = true; 625 suspendOnCheckRunHold = true;
728 lock(m_QueueLock) 626 lock(m_QueueLock)
@@ -730,11 +628,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
730 } 628 }
731 goto checkstate; 629 goto checkstate;
732 630
733 631 // If it's sleeping, remove it from sleep queue and transition it to
734 /* 632 // resetting so no other thread will touch it.
735 * If it's sleeping, remove it from sleep queue and transition it to
736 * resetting so no other thread will touch it.
737 */
738 case XMRInstState.ONSLEEPQ: 633 case XMRInstState.ONSLEEPQ:
739 lock(m_Engine.m_SleepQueue) 634 lock(m_Engine.m_SleepQueue)
740 { 635 {
@@ -747,19 +642,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
747 } 642 }
748 goto checkstate; 643 goto checkstate;
749 644
750 /* 645 // It was just removed from the sleep queue and is about to be put
751 * It was just removed from the sleep queue and is about to be put 646 // on the yield queue (ie, is being woken up).
752 * on the yield queue (ie, is being woken up). 647 // Let that thread complete transition and try again.
753 * Let that thread complete transition and try again.
754 */
755 case XMRInstState.REMDFROMSLPQ: 648 case XMRInstState.REMDFROMSLPQ:
756 Sleep(10); 649 Sleep(10);
757 goto checkstate; 650 goto checkstate;
758 651
759 /* 652 // If it's yielding, remove it from yield queue and transition it to
760 * If it's yielding, remove it from yield queue and transition it to 653 // resetting so no other thread will touch it.
761 * resetting so no other thread will touch it.
762 */
763 case XMRInstState.ONYIELDQ: 654 case XMRInstState.ONYIELDQ:
764 lock(m_Engine.m_YieldQueue) 655 lock(m_Engine.m_YieldQueue)
765 { 656 {
@@ -772,52 +663,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
772 } 663 }
773 goto checkstate; 664 goto checkstate;
774 665
775 /* 666 // If it just finished running something, let that thread transition it
776 * If it just finished running something, let that thread transition it 667 // to its next state then check again.
777 * to its next state then check again.
778 */
779 case XMRInstState.FINISHED: 668 case XMRInstState.FINISHED:
780 Sleep(10); 669 Sleep(10);
781 goto checkstate; 670 goto checkstate;
782 671
783 /* 672 // If it's disposed, that's about as reset as it gets.
784 * If it's disposed, that's about as reset as it gets.
785 */
786 case XMRInstState.DISPOSED: 673 case XMRInstState.DISPOSED:
787 return; 674 return;
788 675
789 /* 676 // Some other thread is already resetting it, let it finish.
790 * Some other thread is already resetting it, let it finish. 677
791 */
792 case XMRInstState.RESETTING: 678 case XMRInstState.RESETTING:
793 return; 679 return;
794 680
795
796 default: 681 default:
797 throw new Exception("bad state"); 682 throw new Exception("bad state");
798 } 683 }
799 684
800 /* 685 // This thread transitioned the instance to RESETTING so reset it.
801 * This thread transitioned the instance to RESETTING so reset it.
802 */
803 lock(m_RunLock) 686 lock(m_RunLock)
804 { 687 {
805 CheckRunLockInvariants(true); 688 CheckRunLockInvariants(true);
806 689
807 /* 690 // No other thread should have transitioned it from RESETTING.
808 * No other thread should have transitioned it from RESETTING.
809 */
810 if(m_IState != XMRInstState.RESETTING) 691 if(m_IState != XMRInstState.RESETTING)
811 throw new Exception("bad state"); 692 throw new Exception("bad state");
812 693
813 /* 694 // Mark it idle now so it can get queued to process new stuff.
814 * Mark it idle now so it can get queued to process new stuff.
815 */
816 m_IState = XMRInstState.IDLE; 695 m_IState = XMRInstState.IDLE;
817 696
818 /* 697 // Reset everything and queue up default's start_entry() event.
819 * Reset everything and queue up default's start_entry() event.
820 */
821 ClearQueue(); 698 ClearQueue();
822 ResetLocked("external Reset"); 699 ResetLocked("external Reset");
823 700
@@ -886,16 +763,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
886 m_SleepUntil = DateTime.MinValue; // not doing llSleep() 763 m_SleepUntil = DateTime.MinValue; // not doing llSleep()
887 m_ResetCount++; // has been reset once more 764 m_ResetCount++; // has been reset once more
888 765
889 /* 766 // Tell next call to 'default state_entry()' to reset all global
890 * Tell next call to 'default state_entry()' to reset all global 767 // vars to their initial values.
891 * vars to their initial values.
892 */
893 doGblInit = true; 768 doGblInit = true;
894 769
895 /* 770 // Set script to 'default' state and queue call to its
896 * Set script to 'default' state and queue call to its 771 // 'state_entry()' event handler.
897 * 'state_entry()' event handler.
898 */
899 m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; 772 m_RunOnePhase = "ResetLocked: posting default:state_entry() event";
900 stateCode = 0; 773 stateCode = 0;
901 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); 774 m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0));
@@ -903,9 +776,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
903 zeroObjectArray, 776 zeroObjectArray,
904 zeroDetectParams)); 777 zeroDetectParams));
905 778
906 /* 779 // Tell CheckRun() to let script run.
907 * Tell CheckRun() to let script run.
908 */
909 suspendOnCheckRunHold = false; 780 suspendOnCheckRunHold = false;
910 suspendOnCheckRunTemp = false; 781 suspendOnCheckRunTemp = false;
911 m_RunOnePhase = "ResetLocked: reset complete"; 782 m_RunOnePhase = "ResetLocked: reset complete";
@@ -955,9 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
955 } 826 }
956 m_CheckRunPhase = "entered"; 827 m_CheckRunPhase = "entered";
957 828
958 /* 829 // Stay stuck in this loop as long as something wants us suspended.
959 * Stay stuck in this loop as long as something wants us suspended.
960 */
961 while(suspendOnCheckRunHold || suspendOnCheckRunTemp) 830 while(suspendOnCheckRunHold || suspendOnCheckRunTemp)
962 { 831 {
963 m_CheckRunPhase = "top of while"; 832 m_CheckRunPhase = "top of while";
@@ -997,10 +866,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
997 866
998 m_CheckRunPhase = "returning"; 867 m_CheckRunPhase = "returning";
999 868
1000 /* 869 // Upon return from CheckRun() it should always be the case that the script is
1001 * Upon return from CheckRun() it should always be the case that the script is 870 // going to process calls normally, neither saving nor restoring stack frame state.
1002 * going to process calls normally, neither saving nor restoring stack frame state.
1003 */
1004 if(callMode != CallMode_NORMAL) 871 if(callMode != CallMode_NORMAL)
1005 throw new Exception("bad callMode " + callMode); 872 throw new Exception("bad callMode " + callMode);
1006 } 873 }
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs
index d3ae165..76762dd 100644
--- a/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs
+++ b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs
@@ -501,10 +501,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
501 */ 501 */
502 public override void EndMethod() 502 public override void EndMethod()
503 { 503 {
504 /* 504 // Convert CIL code to primitive statements.
505 * Convert CIL code to primitive statements. 505 // There are a bunch of labels and internal code such as call stack save restore.
506 * There are a bunch of labels and internal code such as call stack save restore.
507 */
508 topBlock = new OTStmtBlock(); 506 topBlock = new OTStmtBlock();
509 blockstack.Push(topBlock); 507 blockstack.Push(topBlock);
510 for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next) 508 for(LinkedListNode<OTCilInstr> link = cilinstrs.First; link != null; link = link.Next)
@@ -512,10 +510,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
512 link.Value.BuildStatements(this, link); 510 link.Value.BuildStatements(this, link);
513 } 511 }
514 512
515 /* 513 // Strip out stuff we don't want, such as references to callMode.
516 * Strip out stuff we don't want, such as references to callMode. 514 // This strips out stack frame capture and restore code.
517 * This strips out stack frame capture and restore code.
518 */
519 topBlock.StripStuff(null); 515 topBlock.StripStuff(null);
520 516
521 // including a possible final return statement 517 // including a possible final return statement
@@ -532,22 +528,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
532 } 528 }
533 } 529 }
534 530
535 /** 531 // At this point, all behind-the-scenes references are removed except
536 * At this point, all behind-the-scenes references are removed except 532 // that the do/for/if/while blocks are represented by OTStmtCont-style
537 * that the do/for/if/while blocks are represented by OTStmtCont-style 533 // if/jumps. So try to convert them to the higher-level structures.
538 * if/jumps. So try to convert them to the higher-level structures.
539 */
540 topBlock.DetectDoForIfWhile(null); 534 topBlock.DetectDoForIfWhile(null);
541 535
542 /* 536 // Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like.
543 * Final strip to get rid of unneeded @forbreak_<suffix>; labels and the like.
544 */
545 topBlock.StripStuff(null); 537 topBlock.StripStuff(null);
546 538
547 /* 539 // Build reference counts so we don't output unneeded declarations,
548 * Build reference counts so we don't output unneeded declarations, 540 // especially temps and internal variables.
549 * especially temps and internal variables.
550 */
551 foreach(OTLocal local in locals.Values) 541 foreach(OTLocal local in locals.Values)
552 { 542 {
553 local.nlclreads = 0; 543 local.nlclreads = 0;
@@ -564,10 +554,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
564 } 554 }
565 } 555 }
566 556
567 /* 557 // Strip the $n off of local vars that are not ambiguous.
568 * Strip the $n off of local vars that are not ambiguous. 558 // Make sure they don't mask globals and arguments as well.
569 * Make sure they don't mask globals and arguments as well.
570 */
571 Dictionary<string, int> namecounts = new Dictionary<string, int>(); 559 Dictionary<string, int> namecounts = new Dictionary<string, int>();
572 foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values) 560 foreach(Dictionary<int, string> varnames in scriptObjCode.globalVarNames.Values)
573 { 561 {
@@ -607,9 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
607 local.name = name; 595 local.name = name;
608 } 596 }
609 597
610 /* 598 // Print out result.
611 * Print out result.
612 */
613 if(method.Name == _globalvarinit) 599 if(method.Name == _globalvarinit)
614 { 600 {
615 GlobalsDump(); 601 GlobalsDump();
@@ -725,10 +711,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
725 */ 711 */
726 private void GlobalsDump() 712 private void GlobalsDump()
727 { 713 {
728 /* 714 // Scan $globalvarinit(). It should only have global var assignments in it.
729 * Scan $globalvarinit(). It should only have global var assignments in it. 715 // Also gather up list of variables it initializes.
730 * Also gather up list of variables it initializes.
731 */
732 bool badinit = false; 716 bool badinit = false;
733 Dictionary<string, string> inittypes = new Dictionary<string, string>(); 717 Dictionary<string, string> inittypes = new Dictionary<string, string>();
734 foreach(OTStmt stmt in topBlock.blkstmts) 718 foreach(OTStmt stmt in topBlock.blkstmts)
@@ -748,11 +732,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
748 inittypes[globalop.PrintableString] = ""; 732 inittypes[globalop.PrintableString] = "";
749 } 733 }
750 734
751 /* 735 // Scan through list of all global variables in the script.
752 * Scan through list of all global variables in the script. 736 // Output declarations for those what don't have any init statement for them.
753 * Output declarations for those what don't have any init statement for them. 737 // Save the type for those that do have init statements.
754 * Save the type for those that do have init statements.
755 */
756 bool first = true; 738 bool first = true;
757 foreach(string iartypename in scriptObjCode.globalVarNames.Keys) 739 foreach(string iartypename in scriptObjCode.globalVarNames.Keys)
758 { 740 {
@@ -778,10 +760,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
778 } 760 }
779 } 761 }
780 762
781 /* 763 // If $globalvarinit() has anything bad in it, output it as a function.
782 * If $globalvarinit() has anything bad in it, output it as a function. 764 // Otherwise, output it as a series of global declarations with init values.
783 * Otherwise, output it as a series of global declarations with init values.
784 */
785 if(badinit) 765 if(badinit)
786 { 766 {
787 MethodDump(); 767 MethodDump();
@@ -809,19 +789,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
809 { 789 {
810 string indent; 790 string indent;
811 791
812 /* 792 // Event handlers don't have an argument list as such in the original
813 * Event handlers don't have an argument list as such in the original 793 // code. Instead they have a series of assignments from ehargs[] to
814 * code. Instead they have a series of assignments from ehargs[] to 794 // local variables. So make those local variables look like they are
815 * local variables. So make those local variables look like they are 795 // an argument list.
816 * an argument list.
817 */
818 int i = method.Name.IndexOf(' '); 796 int i = method.Name.IndexOf(' ');
819 if(i >= 0) 797 if(i >= 0)
820 { 798 {
821 799 // Maybe we have to output the state name.
822 /*
823 * Maybe we have to output the state name.
824 */
825 string statename = method.Name.Substring(0, i); 800 string statename = method.Name.Substring(0, i);
826 string eventname = method.Name.Substring(++i); 801 string eventname = method.Name.Substring(++i);
827 802
@@ -844,10 +819,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
844 twout.Write('\n'); 819 twout.Write('\n');
845 } 820 }
846 821
847 /* 822 // Output event name and argument list.
848 * Output event name and argument list. 823 // Remove from locals list so they don't print below.
849 * Remove from locals list so they don't print below.
850 */
851 twout.Write('\n' + INDENT + eventname + " ("); 824 twout.Write('\n' + INDENT + eventname + " (");
852 MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname); 825 MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname);
853 i = 0; 826 i = 0;
@@ -873,35 +846,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
873 } 846 }
874 twout.Write(')'); 847 twout.Write(')');
875 848
876 /* 849 // Indent method body by 4 spaces.
877 * Indent method body by 4 spaces.
878 */
879 indent = INDENT; 850 indent = INDENT;
880 } 851 }
881 else 852 else
882 { 853 {
883 854 // Maybe need to close out previous state.
884 /*
885 * Maybe need to close out previous state.
886 */
887 if(laststate != null) 855 if(laststate != null)
888 { 856 {
889 twout.Write("\n}"); 857 twout.Write("\n}");
890 laststate = null; 858 laststate = null;
891 } 859 }
892 860
893 /* 861 // Output blank line and return type (if any).
894 * Output blank line and return type (if any).
895 */
896 twout.Write("\n\n"); 862 twout.Write("\n\n");
897 if(method.ReturnType != typeof(void)) 863 if(method.ReturnType != typeof(void))
898 { 864 {
899 twout.Write(AbbrType(method.ReturnType) + ' '); 865 twout.Write(AbbrType(method.ReturnType) + ' ');
900 } 866 }
901 867
902 /* 868 // Output method name and argument list.
903 * Output method name and argument list.
904 */
905 int j = method.Name.IndexOf('('); 869 int j = method.Name.IndexOf('(');
906 if(j < 0) 870 if(j < 0)
907 { 871 {
@@ -926,15 +890,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
926 twout.Write(')'); 890 twout.Write(')');
927 } 891 }
928 892
929 /* 893 // Don't indent method body at all.
930 * Don't indent method body at all.
931 */
932 indent = ""; 894 indent = "";
933 } 895 }
934 896
935 /* 897 // Output local variable declarations.
936 * Output local variable declarations.
937 */
938 twout.Write('\n' + indent + '{'); 898 twout.Write('\n' + indent + '{');
939 bool didOne = false; 899 bool didOne = false;
940 foreach(OTLocal local in locals.Values) 900 foreach(OTLocal local in locals.Values)
@@ -945,9 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
945 if(didOne) 905 if(didOne)
946 twout.Write('\n'); 906 twout.Write('\n');
947 907
948 /* 908 // Output statements.
949 * Output statements.
950 */
951 if(topBlock.blkstmts.Count == 0) 909 if(topBlock.blkstmts.Count == 0)
952 { 910 {
953 twout.Write(" }"); 911 twout.Write(" }");
@@ -1634,22 +1592,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
1634 { 1592 {
1635 switch(opCode.ToString()) 1593 switch(opCode.ToString())
1636 { 1594 {
1637 1595 // We don't handle non-empty stack at branch points.
1638 /* 1596 //
1639 * We don't handle non-empty stack at branch points. 1597 // So handle this case specially:
1640 * 1598 //
1641 * So handle this case specially: 1599 // dup
1642 * 1600 // ldc.i4.0
1643 * dup 1601 // bge.s llAbstemp << we are here
1644 * ldc.i4.0 1602 // neg
1645 * bge.s llAbstemp << we are here 1603 // llAbstemp:
1646 * neg 1604 //
1647 * llAbstemp: 1605 // becomes:
1648 * 1606 //
1649 * becomes: 1607 // call llAbs
1650 *
1651 * call llAbs
1652 */
1653 case "bge.s": 1608 case "bge.s":
1654 { 1609 {
1655 OTOpnd rite = decompile.opstack.Pop(); // alleged zero 1610 OTOpnd rite = decompile.opstack.Pop(); // alleged zero
@@ -2103,50 +2058,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
2103 2058
2104 public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile) 2059 public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile)
2105 { 2060 {
2106 /* 2061 // arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable
2107 * arg$0.glblVars.iar<type>[<intconst>] is a reference to a global variable 2062 // likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
2108 * likewise so is __xmrinst.glblVars.iar<type>[<intconst>]
2109 */
2110 if((array is OTOpndField) && (index is OTOpndInt)) 2063 if((array is OTOpndField) && (index is OTOpndInt))
2111 { 2064 {
2112 2065 // arrayfield = (arg$0.glblVars).iar<type>
2113 /* 2066 // arrayfieldobj = arg$0.glblVars
2114 * arrayfield = (arg$0.glblVars).iar<type> 2067 // iartypename = iar<type>
2115 * arrayfieldobj = arg$0.glblVars
2116 * iartypename = iar<type>
2117 */
2118 OTOpndField arrayfield = (OTOpndField)array; 2068 OTOpndField arrayfield = (OTOpndField)array;
2119 OTOpnd arrayfieldobj = arrayfield.obj; 2069 OTOpnd arrayfieldobj = arrayfield.obj;
2120 string iartypename = arrayfield.field.Name; 2070 string iartypename = arrayfield.field.Name;
2121 2071
2122 /* 2072 // See if they are what they are supposed to be.
2123 * See if they are what they are supposed to be.
2124 */
2125 if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar")) 2073 if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar"))
2126 { 2074 {
2127 2075 // arrayfieldobjfield = arg$0.glblVars
2128 /*
2129 * arrayfieldobjfield = arg$0.glblVars
2130 */
2131 OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj; 2076 OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj;
2132 2077
2133 /* 2078 // See if the parts are what they are supposed to be.
2134 * See if the parts are what they are supposed to be.
2135 */
2136 if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars")) 2079 if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars"))
2137 { 2080 {
2138 2081 // Everything matches up, make a global variable instead of an array reference.
2139 /*
2140 * Everything matches up, make a global variable instead of an array reference.
2141 */
2142 return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode); 2082 return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode);
2143 } 2083 }
2144 } 2084 }
2145 } 2085 }
2146 2086
2147 /* 2087 // Other array reference.
2148 * Other array reference.
2149 */
2150 OTOpndArrayElem it = new OTOpndArrayElem(); 2088 OTOpndArrayElem it = new OTOpndArrayElem();
2151 it.array = array; 2089 it.array = array;
2152 it.index = index; 2090 it.index = index;
@@ -3097,17 +3035,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3097 return false; 3035 return false;
3098 int listsize = ((OTOpndInt)storeval.index).value; 3036 int listsize = ((OTOpndInt)storeval.index).value;
3099 3037
3100 /* 3038 // Good chance of having list initializer, malloc an object to hold it.
3101 * Good chance of having list initializer, malloc an object to hold it.
3102 */
3103 OTOpndListIni it = new OTOpndListIni(); 3039 OTOpndListIni it = new OTOpndListIni();
3104 it.values = new OTOpnd[listsize]; 3040 it.values = new OTOpnd[listsize];
3105 3041
3106 /* 3042 // There should be exactly listsize statements following that of the form:
3107 * There should be exactly listsize statements following that of the form: 3043 // dup$<n>[<i>] = bla
3108 * dup$<n>[<i>] = bla 3044 // If so, save the bla values in the values[] array.
3109 * If so, save the bla values in the values[] array.
3110 */
3111 LinkedListNode<OTStmt> vallink = link; 3045 LinkedListNode<OTStmt> vallink = link;
3112 for(int i = 0; i < listsize; i++) 3046 for(int i = 0; i < listsize; i++)
3113 { 3047 {
@@ -3129,10 +3063,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3129 it.values[i] = valstore.value; 3063 it.values[i] = valstore.value;
3130 } 3064 }
3131 3065
3132 /* 3066 // The next statement should have a 'newobj list (dup$<n>)' in it somewhere
3133 * The next statement should have a 'newobj list (dup$<n>)' in it somewhere 3067 // that we want to replace with 'it'.
3134 * that we want to replace with 'it'.
3135 */
3136 ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); 3068 ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) });
3137 OTOpnd[] protoargs = new OTOpnd[] { storevar }; 3069 OTOpnd[] protoargs = new OTOpnd[] { storevar };
3138 OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs); 3070 OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs);
@@ -3140,9 +3072,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
3140 vallink = vallink.Next; 3072 vallink = vallink.Next;
3141 bool rc = vallink.Value.ReplaceOperand(proto, it); 3073 bool rc = vallink.Value.ReplaceOperand(proto, it);
3142 3074
3143 /* 3075 // If successful, delete 'dup$n =' and all 'dup$n[i] =' statements.
3144 * If successful, delete 'dup$n =' and all 'dup$n[i] =' statements.
3145 */
3146 if(rc) 3076 if(rc)
3147 { 3077 {
3148 do 3078 do