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

  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.Security.Permissions;
  23.    
  24.    
  25.     public sealed class Eval : AST
  26.     {
  27.         private AST operand;
  28.         private AST unsafeOption;
  29.         private FunctionScope enclosingFunctionScope;
  30.        
  31.         internal Eval(Context context, AST operand, AST unsafeOption) : base(context)
  32.         {
  33.             this.operand = operand;
  34.             this.unsafeOption = unsafeOption;
  35.            
  36.             ScriptObject enclosingScope = Globals.ScopeStack.Peek();
  37.             ((IActivationObject)enclosingScope).GetGlobalScope().evilScript = true;
  38.             if (enclosingScope is ActivationObject)
  39.                 ((ActivationObject)enclosingScope).isKnownAtCompileTime = this.Engine.doFast;
  40.             if (enclosingScope is FunctionScope) {
  41.                 this.enclosingFunctionScope = (FunctionScope)enclosingScope;
  42.                 this.enclosingFunctionScope.mustSaveStackLocals = true;
  43.                 ScriptObject scope = (ScriptObject)this.enclosingFunctionScope.GetParent();
  44.                 while (scope != null) {
  45.                     FunctionScope fscope = scope as FunctionScope;
  46.                     if (fscope != null) {
  47.                         fscope.mustSaveStackLocals = true;
  48.                         fscope.closuresMightEscape = true;
  49.                     }
  50.                     scope = (ScriptObject)scope.GetParent();
  51.                 }
  52.             }
  53.             else
  54.                 this.enclosingFunctionScope = null;
  55.         }
  56.        
  57.         internal override void CheckIfOKToUseInSuperConstructorCall()
  58.         {
  59.             this.context.HandleError(JSError.NotAllowedInSuperConstructorCall);
  60.         }
  61.        
  62.         internal override object Evaluate()
  63.         {
  64.             if (VsaEngine.executeForJSEE)
  65.                 throw new JScriptException(JSError.NonSupportedInDebugger);
  66.             object v = this.operand.Evaluate();
  67.             object u = null;
  68.             if (this.unsafeOption != null)
  69.                 u = this.unsafeOption.Evaluate();
  70.             Globals.CallContextStack.Push(new CallContext(this.context, null, new object[] {v, u}));
  71.             try {
  72.                 try {
  73.                     return JScriptEvaluate(v, u, this.Engine);
  74.                 }
  75.                 catch (JScriptException e) {
  76.                     if (e.context == null) {
  77.                         e.context = this.context;
  78.                     }
  79.                     throw e;
  80.                 }
  81.                 catch (Exception e) {
  82.                     throw new JScriptException(e, this.context);
  83.                 }
  84.                 catch {
  85.                     throw new JScriptException(JSError.NonClsException, this.context);
  86.                 }
  87.             }
  88.             finally {
  89.                 Globals.CallContextStack.Pop();
  90.             }
  91.         }
  92.        
  93.         public static object JScriptEvaluate(object source, VsaEngine engine)
  94.         {
  95.             if (Convert.GetTypeCode(source) != TypeCode.String)
  96.                 return source;
  97.             return Eval.DoEvaluate(source, engine, true);
  98.         }
  99.        
  100.         public static object JScriptEvaluate(object source, object unsafeOption, VsaEngine engine)
  101.         {
  102.             if (Convert.GetTypeCode(source) != TypeCode.String)
  103.                 return source;
  104.             bool isUnsafe = false;
  105.             if (Convert.GetTypeCode(unsafeOption) == TypeCode.String) {
  106.                 if (((IConvertible)unsafeOption).ToString() == "unsafe")
  107.                     isUnsafe = true;
  108.             }
  109.             return Eval.DoEvaluate(source, engine, isUnsafe);
  110.         }
  111.        
  112.         private static object DoEvaluate(object source, VsaEngine engine, bool isUnsafe)
  113.         {
  114.             if (engine.doFast)
  115.                 engine.PushScriptObject(new BlockScope(engine.ScriptObjectStackTop()));
  116.             try {
  117.                 Context context = new Context(new DocumentContext("eval code", engine), ((IConvertible)source).ToString());
  118.                 JSParser p = new JSParser(context);
  119.                 if (!isUnsafe)
  120.                     new SecurityPermission(SecurityPermissionFlag.Execution).PermitOnly();
  121.                 return ((Completion)p.ParseEvalBody().PartiallyEvaluate().Evaluate()).value;
  122.             }
  123.             finally {
  124.                 if (engine.doFast)
  125.                     engine.PopScriptObject();
  126.             }
  127.            
  128.         }
  129.        
  130.         internal override AST PartiallyEvaluate()
  131.         {
  132.             VsaEngine engine = this.Engine;
  133.             ScriptObject scope = Globals.ScopeStack.Peek();
  134.            
  135.             ClassScope cscope = ClassScope.ScopeOfClassMemberInitializer(scope);
  136.             if (null != cscope) {
  137.                 if (cscope.inStaticInitializerCode)
  138.                     cscope.staticInitializerUsesEval = true;
  139.                 else
  140.                     cscope.instanceInitializerUsesEval = true;
  141.             }
  142.            
  143.             if (engine.doFast)
  144.                 engine.PushScriptObject(new BlockScope(scope));
  145.             else {
  146.                 while (scope is WithObject || scope is BlockScope) {
  147.                     if (scope is BlockScope)
  148.                         ((BlockScope)scope).isKnownAtCompileTime = false;
  149.                     scope = scope.GetParent();
  150.                 }
  151.             }
  152.             try {
  153.                 this.operand = this.operand.PartiallyEvaluate();
  154.                 if (this.unsafeOption != null)
  155.                     this.unsafeOption = this.unsafeOption.PartiallyEvaluate();
  156.                 if (this.enclosingFunctionScope != null && this.enclosingFunctionScope.owner == null)
  157.                     this.context.HandleError(JSError.NotYetImplemented);
  158.                 return this;
  159.             }
  160.             finally {
  161.                 if (engine.doFast)
  162.                     this.Engine.PopScriptObject();
  163.             }
  164.         }
  165.        
  166.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  167.         {
  168.             if (this.enclosingFunctionScope != null && this.enclosingFunctionScope.owner != null)
  169.                 this.enclosingFunctionScope.owner.TranslateToILToSaveLocals(il);
  170.             this.operand.TranslateToIL(il, Typeob.Object);
  171.             MethodInfo evaluateMethod = null;
  172.             ConstantWrapper cw = this.unsafeOption as ConstantWrapper;
  173.             if (cw != null) {
  174.                 string s = cw.value as string;
  175.                 if (s != null && s == "unsafe")
  176.                     evaluateMethod = CompilerGlobals.jScriptEvaluateMethod1;
  177.             }
  178.             if (evaluateMethod == null) {
  179.                 evaluateMethod = CompilerGlobals.jScriptEvaluateMethod2;
  180.                 if (this.unsafeOption == null)
  181.                     il.Emit(OpCodes.Ldnull);
  182.                 else
  183.                     this.unsafeOption.TranslateToIL(il, Typeob.Object);
  184.             }
  185.             this.EmitILToLoadEngine(il);
  186.             il.Emit(OpCodes.Call, evaluateMethod);
  187.             Convert.Emit(this, il, Typeob.Object, rtype);
  188.             if (this.enclosingFunctionScope != null && this.enclosingFunctionScope.owner != null)
  189.                 this.enclosingFunctionScope.owner.TranslateToILToRestoreLocals(il);
  190.         }
  191.        
  192.         internal override void TranslateToILInitializer(ILGenerator il)
  193.         {
  194.             this.operand.TranslateToILInitializer(il);
  195.             if (this.unsafeOption != null)
  196.                 this.unsafeOption.TranslateToILInitializer(il);
  197.         }
  198.     }
  199. }

Developer Fusion