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

  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. /*
  19.     A stack frame is used to avoid allocating the name lookup hash table until it is actually needed.
  20.    
  21.     Rather than allocating the hash table directly and then duplicating code that already resides in JSObject and FunctionScope,
  22.     a FunctionScope is allocated and populated whenever the hashtable is needed for a name lookup.
  23.     */   
  24.    
  25.     using Microsoft.JScript.Vsa;
  26.     using System;
  27.     using System.Reflection;
  28.     using System.Collections;
  29.     using System.Diagnostics;
  30.    
  31.     public sealed class StackFrame : ScriptObject, IActivationObject
  32.     {
  33.         internal ArgumentsObject caller_arguments;
  34.         private JSLocalField[] fields;
  35.         public object[] localVars;
  36.         private FunctionScope nestedFunctionScope;
  37.         internal object thisObject;
  38.         public object closureInstance;
  39.        
  40.         internal StackFrame(ScriptObject parent, JSLocalField[] fields, object[] local_vars, object thisObject) : base(parent)
  41.         {
  42.             this.caller_arguments = null;
  43.             this.fields = fields;
  44.             this.localVars = local_vars;
  45.             this.nestedFunctionScope = null;
  46.             this.thisObject = thisObject;
  47.             if (parent is StackFrame)
  48.                 this.closureInstance = ((StackFrame)parent).closureInstance;
  49.             else if (parent is JSObject)
  50.                 this.closureInstance = parent;
  51.             else
  52.                 this.closureInstance = null;
  53.         }
  54.        
  55.         internal JSVariableField AddNewField(string name, object value, FieldAttributes attributeFlags)
  56.         {
  57.             this.AllocateFunctionScope();
  58.             return this.nestedFunctionScope.AddNewField(name, value, attributeFlags);
  59.         }
  60.        
  61.         private void AllocateFunctionScope()
  62.         {
  63.             if (this.nestedFunctionScope != null)
  64.                 return;
  65.             this.nestedFunctionScope = new FunctionScope(this.parent);
  66.             if (this.fields != null)
  67.                 for (int i = 0int n = this.fields.Length; i < n; i++)
  68.                     this.nestedFunctionScope.AddOuterScopeField(this.fields[i].Name, this.fields[i]);
  69.         }
  70.        
  71.         public object GetDefaultThisObject()
  72.         {
  73.             ScriptObject parent = this.GetParent();
  74.             IActivationObject iob = parent as IActivationObject;
  75.             if (iob != null)
  76.                 return iob.GetDefaultThisObject();
  77.             return parent;
  78.         }
  79.        
  80.         public FieldInfo GetField(string name, int lexLevel)
  81.         {
  82.             return null;
  83.         }
  84.        
  85.         public GlobalScope GetGlobalScope()
  86.         {
  87.             return ((IActivationObject)this.GetParent()).GetGlobalScope();
  88.         }
  89.        
  90.         FieldInfo IActivationObject.GetLocalField(string name)
  91.         {
  92.             this.AllocateFunctionScope();
  93.             return this.nestedFunctionScope.GetLocalField(name);
  94.         }
  95.        
  96.         public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
  97.         {
  98.             this.AllocateFunctionScope();
  99.             return this.nestedFunctionScope.GetMember(name, bindingAttr);
  100.         }
  101.        
  102.         public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
  103.         {
  104.             this.AllocateFunctionScope();
  105.             return this.nestedFunctionScope.GetMembers(bindingAttr);
  106.         }
  107.        
  108.         internal override void GetPropertyEnumerator(ArrayList enums, ArrayList objects)
  109.         {
  110.             throw new JScriptException(JSError.InternalError);
  111.         }
  112.        
  113.         #if !DEBUG
  114.         [DebuggerStepThroughAttribute()]
  115.         [DebuggerHiddenAttribute()]
  116.         #endif
  117.         internal override object GetMemberValue(string name)
  118.         {
  119.             this.AllocateFunctionScope();
  120.             return this.nestedFunctionScope.GetMemberValue(name);
  121.         }
  122.        
  123.         #if !DEBUG
  124.         [DebuggerStepThroughAttribute()]
  125.         [DebuggerHiddenAttribute()]
  126.         #endif
  127.         public object GetMemberValue(string name, int lexlevel)
  128.         {
  129.             if (lexlevel <= 0)
  130.                 return Missing.Value;
  131.             if (this.nestedFunctionScope != null)
  132.                 return this.nestedFunctionScope.GetMemberValue(name, lexlevel);
  133.             else
  134.                 return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel - 1);
  135.         }
  136.        
  137.         public static void PushStackFrameForStaticMethod(RuntimeTypeHandle thisclass, JSLocalField[] fields, VsaEngine engine)
  138.         {
  139.             PushStackFrameForMethod(Type.GetTypeFromHandle(thisclass), fields, engine);
  140.         }
  141.        
  142.         public static void PushStackFrameForMethod(object thisob, JSLocalField[] fields, VsaEngine engine)
  143.         {
  144.             Globals globals = engine.Globals;
  145.             IActivationObject top = (IActivationObject)globals.ScopeStack.Peek();
  146.             string currentNamespace = thisob.GetType().Namespace;
  147.             WithObject wob = null;
  148.             if (currentNamespace != null && currentNamespace.Length > 0) {
  149.                 wob = new WithObject(top.GetGlobalScope(), new WrappedNamespace(currentNamespace, engine));
  150.                 wob.isKnownAtCompileTime = true;
  151.                 //For use by an eval inside this method
  152.                 wob = new WithObject(wob, thisob);
  153.             }
  154.             else
  155.                 wob = new WithObject(top.GetGlobalScope(), thisob);
  156.             wob.isKnownAtCompileTime = true;
  157.             StackFrame sf = new StackFrame(wob, fields, new object[fields.Length], thisob);
  158.             sf.closureInstance = thisob;
  159.             globals.ScopeStack.GuardedPush(sf);
  160.         }
  161.        
  162.         #if !DEBUG
  163.         [DebuggerStepThroughAttribute()]
  164.         [DebuggerHiddenAttribute()]
  165.         #endif
  166.         internal override void SetMemberValue(string name, object value)
  167.         {
  168.             this.AllocateFunctionScope();
  169.             this.nestedFunctionScope.SetMemberValue(name, value, this);
  170.         }
  171.     }
  172. }

Developer Fusion