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

  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.    
  23.     public sealed class With : AST
  24.     {
  25.         private AST obj;
  26.         private AST block;
  27.         private Completion completion;
  28.         private FunctionScope enclosing_function;
  29.        
  30.         internal With(Context context, AST obj, AST block) : base(context)
  31.         {
  32.             this.obj = obj;
  33.             this.block = block;
  34.             this.completion = new Completion();
  35.             ScriptObject scope = Globals.ScopeStack.Peek();
  36.             if (scope is FunctionScope)
  37.                 this.enclosing_function = (FunctionScope)scope;
  38.             else
  39.                 this.enclosing_function = null;
  40.         }
  41.        
  42.         internal override object Evaluate()
  43.         {
  44.             try {
  45.                 JScriptWith(this.obj.Evaluate(), this.Engine);
  46.             }
  47.             catch (JScriptException e) {
  48.                 e.context = this.obj.context;
  49.                 throw e;
  50.             }
  51.             Completion c = null;
  52.             try {
  53.                 c = (Completion)this.block.Evaluate();
  54.             }
  55.             finally {
  56.                 Globals.ScopeStack.Pop();
  57.             }
  58.             if (c.Continue > 1)
  59.                 this.completion.Continue = c.Continue - 1;
  60.             else
  61.                 this.completion.Continue = 0;
  62.             if (c.Exit > 0)
  63.                 this.completion.Exit = c.Exit - 1;
  64.             else
  65.                 this.completion.Exit = 0;
  66.             if (c.Return)
  67.                 return c;
  68.             return this.completion;
  69.         }
  70.        
  71.         public static object JScriptWith(object withOb, VsaEngine engine)
  72.         {
  73.             object ob = Convert.ToObject(withOb, engine);
  74.             if (ob == null)
  75.                 throw new JScriptException(JSError.ObjectExpected);
  76.             Globals glob = engine.Globals;
  77.             glob.ScopeStack.GuardedPush(new WithObject(glob.ScopeStack.Peek(), ob));
  78.             return ob;
  79.         }
  80.        
  81.         internal override AST PartiallyEvaluate()
  82.         {
  83.             this.obj = this.obj.PartiallyEvaluate();
  84.             WithObject wob;
  85.             if (this.obj is ConstantWrapper) {
  86.                 object ob = Convert.ToObject(this.obj.Evaluate(), this.Engine);
  87.                 wob = new WithObject(Globals.ScopeStack.Peek(), ob);
  88.                 if (ob is JSObject && ((JSObject)ob).noExpando)
  89.                     wob.isKnownAtCompileTime = true;
  90.             }
  91.             else
  92.                 wob = new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false));
  93.             Globals.ScopeStack.Push(wob);
  94.             try {
  95.                 this.block = this.block.PartiallyEvaluate();
  96.             }
  97.             finally {
  98.                 Globals.ScopeStack.Pop();
  99.             }
  100.             return this;
  101.         }
  102.        
  103.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  104.         {
  105.             //This assumes that rtype == Void.class
  106.             this.context.EmitLineInfo(il);
  107.             Globals.ScopeStack.Push(new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false)));
  108.             bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
  109.             compilerGlobals.InsideProtectedRegion = true;
  110.             Label lab = il.DefineLabel();
  111.             compilerGlobals.BreakLabelStack.Push(lab);
  112.             compilerGlobals.ContinueLabelStack.Push(lab);
  113.             this.obj.TranslateToIL(il, Typeob.Object);
  114.             this.EmitILToLoadEngine(il);
  115.             il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod);
  116.             // JScriptWith returns the with object as an 'Object' (used by the debugger EE)
  117.             // define a local named 'with()' that the debugger EE will use to bind to the with object
  118.             LocalBuilder withObj = null;
  119.             if (context.document.debugOn) {
  120.                 il.BeginScope();
  121.                 // used by the debugger to mark a with block
  122.                 withObj = il.DeclareLocal(Typeob.Object);
  123.                 withObj.SetLocalSymInfo("with()");
  124.                 il.Emit(OpCodes.Stloc, withObj);
  125.             }
  126.             else
  127.                 il.Emit(OpCodes.Pop);
  128.            
  129.             il.BeginExceptionBlock();
  130.             this.block.TranslateToILInitializer(il);
  131.             this.block.TranslateToIL(il, Typeob.Void);
  132.             il.BeginFinallyBlock();
  133.             if (context.document.debugOn) {
  134.                 // null the local used by the debugger EE
  135.                 il.Emit(OpCodes.Ldnull);
  136.                 il.Emit(OpCodes.Stloc, withObj);
  137.             }
  138.             this.EmitILToLoadEngine(il);
  139.             il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
  140.             il.Emit(OpCodes.Pop);
  141.             il.EndExceptionBlock();
  142.             if (context.document.debugOn)
  143.                 il.EndScope();
  144.             // used by the debugger to mark a with block
  145.             il.MarkLabel(lab);
  146.             compilerGlobals.BreakLabelStack.Pop();
  147.             compilerGlobals.ContinueLabelStack.Pop();
  148.             compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
  149.             Globals.ScopeStack.Pop();
  150.         }
  151.        
  152.         internal override void TranslateToILInitializer(ILGenerator il)
  153.         {
  154.             this.obj.TranslateToILInitializer(il);
  155.         }
  156.     }
  157. }

Developer Fusion