diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs | 1951 |
1 files changed, 663 insertions, 1288 deletions
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 | } |