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

  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 abstract class AST
  24.     {
  25.         internal Context context;
  26.        
  27.         internal AST(Context context)
  28.         {
  29.             this.context = context;
  30.         }
  31.        
  32.         internal virtual void CheckIfOKToUseInSuperConstructorCall()
  33.         {
  34.         }
  35.        
  36.         internal CompilerGlobals compilerGlobals {
  37.             get { return this.context.document.compilerGlobals; }
  38.         }
  39.        
  40.         internal virtual bool Delete()
  41.         {
  42.             return true;
  43.             //This is according to spec, but not backwards compatible with JS5. The latter throws an exception.
  44.         }
  45.        
  46.         //Run up the scope chain until a FunctionScope or GlobalScope/StackFrame is encountered.
  47.         //For a FunctionScope, defer to the owner.
  48.         //For a ClassScope, get the engine from a CRS static, or make a new engine
  49.         //For the GlobalScope, load the corresponding field of the this object.
  50.        
  51.         internal void EmitILToLoadEngine(ILGenerator il)
  52.         {
  53.             ScriptObject scope = this.Engine.ScriptObjectStackTop();
  54.             while (scope != null && (scope is WithObject || scope is BlockScope))
  55.                 scope = scope.GetParent();
  56.             if (scope is FunctionScope)
  57.                 ((FunctionScope)scope).owner.TranslateToILToLoadEngine(il);
  58.             else if (scope is ClassScope)
  59.                 if (this.Engine.doCRS)
  60.                     il.Emit(OpCodes.Ldsfld, CompilerGlobals.contextEngineField);
  61.                 else/*
  62.             else //inside a static initializer
  63.             if (this.Engine.doCRS)       
  64.               il.Emit(OpCodes.Ldsfld, CompilerGlobals.contextEngineField);
  65.             else
  66.               il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngine);*/               
  67.                 //Inside a static initializer routine
  68. {
  69.                     if (this.context.document.engine.PEFileKind == PEFileKinds.Dll) {
  70.                         il.Emit(OpCodes.Ldtoken, ((ClassScope)scope).GetTypeBuilder());
  71.                         il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngineWithType);
  72.                     }
  73.                     else
  74.                         il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngine);
  75.                 }
  76.             else {
  77.                 //NOTE: a StackFrame is ecountered at compile time only when there is an eval.
  78.                 //Eval does not translate to IL so we should only get here if the scope is a GlobalScope
  79.                 Debug.Assert(scope is GlobalScope);
  80.                 il.Emit(OpCodes.Ldarg_0);
  81.                 il.Emit(OpCodes.Ldfld, CompilerGlobals.engineField);
  82.             }
  83.         }
  84.        
  85.         internal VsaEngine Engine {
  86.             get { return this.context.document.engine; }
  87.         }
  88.        
  89.         internal abstract object Evaluate();
  90.        
  91.         internal virtual LateBinding EvaluateAsLateBinding()
  92.         {
  93.             return new LateBinding(null, this.Evaluate(), VsaEngine.executeForJSEE);
  94.         }
  95.        
  96.         internal virtual WrappedNamespace EvaluateAsWrappedNamespace(bool giveErrorIfNameInUse)
  97.         {
  98.             throw new JScriptException(JSError.InternalError, this.context);
  99.         }
  100.        
  101.         internal Globals Globals {
  102.             get { return this.context.document.engine.Globals; }
  103.         }
  104.        
  105.         internal virtual bool HasReturn()
  106.         {
  107.             return false;
  108.         }
  109.        
  110.         internal virtual IReflect InferType(JSField inference_target)
  111.         {
  112.             return Typeob.Object;
  113.         }
  114.        
  115.        
  116.         internal virtual void InvalidateInferredTypes()
  117.         {
  118.             //No need to do anything at this level.
  119.         }
  120.        
  121.         internal virtual bool OkToUseAsType()
  122.         {
  123.             return false;
  124.         }
  125.        
  126.         internal abstract AST PartiallyEvaluate();
  127.        
  128.         internal virtual AST PartiallyEvaluateAsCallable()
  129.         {
  130.             return new CallableExpression(this.PartiallyEvaluate());
  131.         }
  132.        
  133.         internal virtual AST PartiallyEvaluateAsReference()
  134.         {
  135.             return this.PartiallyEvaluate();
  136.         }
  137.        
  138.         internal virtual void ResolveCall(ASTList args, IReflect[] argIRs, bool constructor, bool brackets)
  139.         {
  140.             throw new JScriptException(JSError.InternalError, this.context);
  141.         }
  142.        
  143.         internal virtual object ResolveCustomAttribute(ASTList args, IReflect[] argIRs, AST target)
  144.         {
  145.             throw new JScriptException(JSError.InternalError, this.context);
  146.         }
  147.        
  148.         internal virtual void SetPartialValue(AST partial_value)
  149.         {
  150.             this.context.HandleError(JSError.IllegalAssignment);
  151.         }
  152.        
  153.         internal virtual void SetValue(object value)
  154.         {
  155.             this.context.HandleError(JSError.IllegalAssignment);
  156.         }
  157.        
  158.         internal virtual void TranslateToConditionalBranch(ILGenerator il, bool branchIfTrue, Label label, bool shortForm)
  159.         {
  160.             //This method is overridden in all interesting cases.
  161.             IReflect ir = this.InferType(null);
  162.             if (ir != Typeob.Object && ir is Type) {
  163.                 string op = branchIfTrue ? "op_True" : "op_False";
  164.                 MethodInfo meth = ir.GetMethod(op, BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {(Type)ir}, null);
  165.                 if (meth != null) {
  166.                     this.TranslateToIL(il, (Type)ir);
  167.                     il.Emit(OpCodes.Call, meth);
  168.                     il.Emit(OpCodes.Brtrue, label);
  169.                     return;
  170.                 }
  171.             }
  172.             Type t = Convert.ToType(ir);
  173.             this.TranslateToIL(il, t);
  174.             Convert.Emit(this, il, t, Typeob.Boolean, true);
  175.             if (branchIfTrue)
  176.                 il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label);
  177.             else
  178.                 il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label);
  179.         }
  180.        
  181.         internal abstract void TranslateToIL(ILGenerator il, Type rtype);
  182.        
  183.         internal virtual void TranslateToILCall(ILGenerator il, Type rtype, ASTList args, bool construct, bool brackets)
  184.         {
  185.             throw new JScriptException(JSError.InternalError, this.context);
  186.         }
  187.        
  188.         internal virtual void TranslateToILDelete(ILGenerator il, Type rtype)
  189.         {
  190.             if (rtype != Typeob.Void) {
  191.                 il.Emit(OpCodes.Ldc_I4_1);
  192.                 //This is according to spec, but not backwards compatible with JS5. The latter throws an exception.
  193.                 Convert.Emit(this, il, Typeob.Boolean, rtype);
  194.             }
  195.         }
  196.        
  197.         internal virtual void TranslateToILInitializer(ILGenerator il)
  198.         {
  199.             throw new JScriptException(JSError.InternalError, this.context);
  200.         }
  201.        
  202.         internal virtual void TranslateToILPreSet(ILGenerator il)
  203.         {
  204.             throw new JScriptException(JSError.InternalError, this.context);
  205.         }
  206.        
  207.         internal virtual void TranslateToILPreSet(ILGenerator il, ASTList args)
  208.         {
  209.             this.TranslateToIL(il, Typeob.Object);
  210.             args.TranslateToIL(il, Typeob.ArrayOfObject);
  211.         }
  212.        
  213.         internal virtual void TranslateToILPreSetPlusGet(ILGenerator il)
  214.         {
  215.             throw new JScriptException(JSError.InternalError, this.context);
  216.         }
  217.        
  218.         internal virtual void TranslateToILPreSetPlusGet(ILGenerator il, ASTList args, bool inBrackets)
  219.         {
  220.             il.Emit(OpCodes.Ldnull);
  221.             //Put a dummy this obj on the stack for CallValue's sake
  222.             this.TranslateToIL(il, Typeob.Object);
  223.             il.Emit(OpCodes.Dup);
  224.             LocalBuilder savedOb = il.DeclareLocal(Typeob.Object);
  225.             il.Emit(OpCodes.Stloc, savedOb);
  226.             args.TranslateToIL(il, Typeob.ArrayOfObject);
  227.             il.Emit(OpCodes.Dup);
  228.             LocalBuilder savedArgs = il.DeclareLocal(Typeob.ArrayOfObject);
  229.             il.Emit(OpCodes.Stloc, savedArgs);
  230.             il.Emit(OpCodes.Ldc_I4_0);
  231.             if (inBrackets)
  232.                 il.Emit(OpCodes.Ldc_I4_1);
  233.             else
  234.                 il.Emit(OpCodes.Ldc_I4_0);
  235.             this.EmitILToLoadEngine(il);
  236.             il.Emit(OpCodes.Call, CompilerGlobals.callValueMethod);
  237.             LocalBuilder savedResult = il.DeclareLocal(Typeob.Object);
  238.             il.Emit(OpCodes.Stloc, savedResult);
  239.             il.Emit(OpCodes.Ldloc, savedOb);
  240.             il.Emit(OpCodes.Ldloc, savedArgs);
  241.             il.Emit(OpCodes.Ldloc, savedResult);
  242.         }
  243.        
  244.         internal void TranslateToILSet(ILGenerator il)
  245.         {
  246.             this.TranslateToILSet(il, null);
  247.         }
  248.        
  249.         internal virtual void TranslateToILSet(ILGenerator il, AST rhvalue)
  250.         {
  251.             if (rhvalue != null)
  252.                 rhvalue.TranslateToIL(il, Typeob.Object);
  253.             il.Emit(OpCodes.Call, CompilerGlobals.setIndexedPropertyValueStaticMethod);
  254.         }
  255.        
  256.         internal virtual object TranslateToILReference(ILGenerator il, Type rtype)
  257.         {
  258.             this.TranslateToIL(il, rtype);
  259.             LocalBuilder tok = il.DeclareLocal(rtype);
  260.             il.Emit(OpCodes.Stloc, tok);
  261.             il.Emit(OpCodes.Ldloca, tok);
  262.             return tok;
  263.         }
  264.        
  265.         internal virtual Context GetFirstExecutableContext()
  266.         {
  267.             return this.context;
  268.         }
  269.        
  270.        
  271.     }
  272. }

Developer Fusion