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

  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 ArrayLiteral : AST
  24.     {
  25.         internal ASTList elements;
  26.        
  27.         public ArrayLiteral(Context context, ASTList elements) : base(context)
  28.         {
  29.             this.elements = elements;
  30.         }
  31.        
  32.         internal bool AssignmentCompatible(IReflect lhir, bool reportError)
  33.         {
  34.             if (lhir == Typeob.Object || lhir == Typeob.Array || lhir is ArrayObject)
  35.                 return true;
  36.             IReflect target_element_ir;
  37.             if (lhir == Typeob.Array)
  38.                 target_element_ir = Typeob.Object;
  39.             else if (lhir is TypedArray) {
  40.                 TypedArray tArr = ((TypedArray)lhir);
  41.                 if (tArr.rank != 1) {
  42.                     this.context.HandleError(JSError.TypeMismatch, reportError);
  43.                     return false;
  44.                 }
  45.                 target_element_ir = tArr.elementType;
  46.             }
  47.             else if (lhir is Type && ((Type)lhir).IsArray) {
  48.                 Type t = ((Type)lhir);
  49.                 if (t.GetArrayRank() != 1) {
  50.                     this.context.HandleError(JSError.TypeMismatch, reportError);
  51.                     return false;
  52.                 }
  53.                 target_element_ir = t.GetElementType();
  54.             }
  55.             else
  56.                 return false;
  57.             for (int i = 0int n = this.elements.count; i < n; i++)
  58.                 if (!Binding.AssignmentCompatible(target_element_ir, this.elements[i], this.elements[i].InferType(null), reportError))
  59.                     return false;
  60.             return true;
  61.         }
  62.        
  63.         internal override void CheckIfOKToUseInSuperConstructorCall()
  64.         {
  65.             for (int i = 0int n = this.elements.count; i < n; i++)
  66.                 this.elements[i].CheckIfOKToUseInSuperConstructorCall();
  67.         }
  68.        
  69.         internal override object Evaluate()
  70.         {
  71.             if (VsaEngine.executeForJSEE)
  72.                 throw new JScriptException(JSError.NonSupportedInDebugger);
  73.             int n = this.elements.count;
  74.             object[] elems = new object[n];
  75.             for (int i = 0; i < n; i++)
  76.                 elems[i] = this.elements[i].Evaluate();
  77.             return this.Engine.GetOriginalArrayConstructor().ConstructArray(elems);
  78.         }
  79.        
  80.         internal bool IsOkToUseInCustomAttribute()
  81.         {
  82.             int n = this.elements.count;
  83.             for (int i = 0; i < n; i++) {
  84.                 object elem = this.elements[i];
  85.                 if (!(elem is ConstantWrapper))
  86.                     return false;
  87.                 if (CustomAttribute.TypeOfArgument(((ConstantWrapper)elem).Evaluate()) == null)
  88.                     return false;
  89.             }
  90.             return true;
  91.         }
  92.        
  93.         internal override AST PartiallyEvaluate()
  94.         {
  95.             int n = this.elements.count;
  96.             for (int i = 0; i < n; i++)
  97.                 this.elements[i] = this.elements[i].PartiallyEvaluate();
  98.             return this;
  99.         }
  100.        
  101.         internal override IReflect InferType(JSField inference_target)
  102.         {
  103.             return Typeob.ArrayObject;
  104.         }
  105.        
  106.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  107.         {
  108.             if (rtype == Typeob.Array) {
  109.                 this.TranslateToILArray(il, Typeob.Object);
  110.                 return;
  111.             }
  112.             if (rtype.IsArray && rtype.GetArrayRank() == 1) {
  113.                 this.TranslateToILArray(il, rtype.GetElementType());
  114.                 return;
  115.             }
  116.             int n = this.elements.count;
  117.             MethodInfo constructorMethod = null;
  118.             if (this.Engine.Globals.globalObject is LenientGlobalObject) {
  119.                 this.EmitILToLoadEngine(il);
  120.                 il.Emit(OpCodes.Call, CompilerGlobals.getOriginalArrayConstructorMethod);
  121.                 constructorMethod = CompilerGlobals.constructArrayMethod;
  122.             }
  123.             else
  124.                 constructorMethod = CompilerGlobals.fastConstructArrayLiteralMethod;
  125.             ConstantWrapper.TranslateToILInt(il, n);
  126.             il.Emit(OpCodes.Newarr, Typeob.Object);
  127.             for (int i = 0; i < n; i++) {
  128.                 il.Emit(OpCodes.Dup);
  129.                 ConstantWrapper.TranslateToILInt(il, i);
  130.                 this.elements[i].TranslateToIL(il, Typeob.Object);
  131.                 il.Emit(OpCodes.Stelem_Ref);
  132.             }
  133.             il.Emit(OpCodes.Call, constructorMethod);
  134.             Convert.Emit(this, il, Typeob.ArrayObject, rtype);
  135.         }
  136.        
  137.         private void TranslateToILArray(ILGenerator il, Type etype)
  138.         {
  139.             int n = this.elements.count;
  140.             ConstantWrapper.TranslateToILInt(il, n);
  141.             TypeCode ecode = Type.GetTypeCode(etype);
  142.             il.Emit(OpCodes.Newarr, etype);
  143.             for (int i = 0; i < n; i++) {
  144.                 il.Emit(OpCodes.Dup);
  145.                 ConstantWrapper.TranslateToILInt(il, i);
  146.                 if (etype.IsValueType && !etype.IsPrimitive)
  147.                     il.Emit(OpCodes.Ldelema, etype);
  148.                 this.elements[i].TranslateToIL(il, etype);
  149.                 Binding.TranslateToStelem(il, etype);
  150.             }
  151.         }
  152.        
  153.         internal override void TranslateToILInitializer(ILGenerator il)
  154.         {
  155.             for (int i = 0int n = this.elements.count; i < n; i++)
  156.                 this.elements[i].TranslateToILInitializer(il);
  157.         }
  158.     }
  159. }

Developer Fusion