The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ RegExpLiteral

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using Microsoft.JScript.Vsa;
  19.     using System;
  20.     using System.Reflection;
  21.     using System.Reflection.Emit;
  22.     using System.Globalization;
  23.    
  24.     internal sealed class RegExpLiteral : AST
  25.     {
  26.         private string source;
  27.         private bool ignoreCase, global, multiline;
  28.         private JSGlobalField regExpVar;
  29.        
  30.         private static int counter = 0;
  31.        
  32.        
  33.         internal RegExpLiteral(string source, string flags, Context context) : base(context)
  34.         {
  35.             this.source = source;
  36.             this.ignoreCase = this.global = this.multiline = false;
  37.             if (flags != null)
  38.                 for (int i = 0; i < flags.Length; i++)
  39.                     switch (flags[i]) {
  40.                         case 'i':
  41.                             if (this.ignoreCase)
  42.                                 throw new JScriptException(JSError.RegExpSyntax);
  43.                             this.ignoreCase = true;
  44.                             break;
  45.                         case 'g':
  46.                             if (this.global)
  47.                                 throw new JScriptException(JSError.RegExpSyntax);
  48.                             this.global = true;
  49.                             break;
  50.                         case 'm':
  51.                             if (this.multiline)
  52.                                 throw new JScriptException(JSError.RegExpSyntax);
  53.                             this.multiline = true;
  54.                             break;
  55.                         default:
  56.                             throw new JScriptException(JSError.RegExpSyntax);
  57.                             break;
  58.                     }
  59.         }
  60.        
  61.         internal override object Evaluate()
  62.         {
  63.             if (VsaEngine.executeForJSEE)
  64.                 throw new JScriptException(JSError.NonSupportedInDebugger);
  65.             RegExpObject regExpObject = (RegExpObject)Globals.RegExpTable[this];
  66.             if (regExpObject == null) {
  67.                 regExpObject = (RegExpObject)this.Engine.GetOriginalRegExpConstructor().Construct(this.source, this.ignoreCase, this.global, this.multiline);
  68.                 Globals.RegExpTable[this] = regExpObject;
  69.             }
  70.             return regExpObject;
  71.         }
  72.        
  73.         internal override IReflect InferType(JSField inferenceTarget)
  74.         {
  75.             return Typeob.RegExpObject;
  76.         }
  77.        
  78.         internal override AST PartiallyEvaluate()
  79.         {
  80.             string id = "regexp " + (RegExpLiteral.counter++).ToString(CultureInfo.InvariantCulture);
  81.             GlobalScope gs = (GlobalScope)this.Engine.GetGlobalScope().GetObject();
  82.             JSGlobalField v = (JSGlobalField)gs.AddNewField(id, null, FieldAttributes.Assembly);
  83.             v.type = new TypeExpression(new ConstantWrapper(Typeob.RegExpObject, this.context));
  84.             this.regExpVar = v;
  85.             return this;
  86.         }
  87.        
  88.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  89.         {
  90.             il.Emit(OpCodes.Ldsfld, (FieldInfo)this.regExpVar.GetMetaData());
  91.             Convert.Emit(this, il, Typeob.RegExpObject, rtype);
  92.         }
  93.        
  94.         internal override void TranslateToILInitializer(ILGenerator il)
  95.         {
  96.             ScriptObject scope = this.Engine.ScriptObjectStackTop();
  97.             while (scope != null && (scope is WithObject || scope is BlockScope))
  98.                 scope = scope.GetParent();
  99.             if (scope is FunctionScope) {
  100.                 this.EmitILToLoadEngine(il);
  101.                 //Make sure engine gets initialized every time function is entered
  102.                 il.Emit(OpCodes.Pop);
  103.             }
  104.             il.Emit(OpCodes.Ldsfld, (FieldInfo)this.regExpVar.GetMetaData());
  105.             Label exit = il.DefineLabel();
  106.             il.Emit(OpCodes.Brtrue_S, exit);
  107.             this.EmitILToLoadEngine(il);
  108.             il.Emit(OpCodes.Call, CompilerGlobals.getOriginalRegExpConstructorMethod);
  109.             il.Emit(OpCodes.Ldstr, this.source);
  110.             if (this.ignoreCase)
  111.                 il.Emit(OpCodes.Ldc_I4_1);
  112.             else
  113.                 il.Emit(OpCodes.Ldc_I4_0);
  114.             if (this.global)
  115.                 il.Emit(OpCodes.Ldc_I4_1);
  116.             else
  117.                 il.Emit(OpCodes.Ldc_I4_0);
  118.             if (this.multiline)
  119.                 il.Emit(OpCodes.Ldc_I4_1);
  120.             else
  121.                 il.Emit(OpCodes.Ldc_I4_0);
  122.             il.Emit(OpCodes.Call, CompilerGlobals.regExpConstructMethod);
  123.             il.Emit(OpCodes.Castclass, Typeob.RegExpObject);
  124.             il.Emit(OpCodes.Stsfld, (FieldInfo)this.regExpVar.GetMetaData());
  125.             il.MarkLabel(exit);
  126.         }
  127.     }
  128. }

Developer Fusion