ArrayConstructor.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System.Collections;
  2. using Jint.Native.Function;
  3. using Jint.Native.Object;
  4. using Jint.Runtime;
  5. using Jint.Runtime.Interop;
  6. namespace Jint.Native.Array
  7. {
  8. public sealed class ArrayConstructor : FunctionInstance, IConstructor
  9. {
  10. private ArrayConstructor(Engine engine) : base(engine, null, null, false)
  11. {
  12. }
  13. public ArrayPrototype PrototypeObject { get; private set; }
  14. public static ArrayConstructor CreateArrayConstructor(Engine engine)
  15. {
  16. var obj = new ArrayConstructor(engine);
  17. obj.Extensible = true;
  18. // The value of the [[Prototype]] internal property of the Array constructor is the Function prototype object
  19. obj.Prototype = engine.Function.PrototypeObject;
  20. obj.PrototypeObject = ArrayPrototype.CreatePrototypeObject(engine, obj);
  21. obj.FastAddProperty("length", 1, false, false, false);
  22. // The initial value of Array.prototype is the Array prototype object
  23. obj.FastAddProperty("prototype", obj.PrototypeObject, false, false, false);
  24. return obj;
  25. }
  26. public void Configure()
  27. {
  28. FastAddProperty("isArray", new ClrFunctionInstance(Engine, IsArray, 1), true, false, true);
  29. }
  30. private JsValue IsArray(JsValue thisObj, JsValue[] arguments)
  31. {
  32. if (arguments.Length == 0)
  33. {
  34. return false;
  35. }
  36. var o = arguments.At(0);
  37. return o.IsObject() && o.AsObject().Class == "Array";
  38. }
  39. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  40. {
  41. return Construct(arguments);
  42. }
  43. public ObjectInstance Construct(JsValue[] arguments)
  44. {
  45. var instance = new ArrayInstance(Engine);
  46. instance.Prototype = PrototypeObject;
  47. instance.Extensible = true;
  48. if (arguments.Length == 1 && arguments.At(0).IsNumber())
  49. {
  50. var length = TypeConverter.ToUint32(arguments.At(0));
  51. if (!TypeConverter.ToNumber(arguments[0]).Equals(length))
  52. {
  53. throw new JavaScriptException(Engine.RangeError);
  54. }
  55. instance.FastAddProperty("length", length, true, false, false);
  56. }
  57. else if (arguments.Length == 1 && arguments.At(0).IsObject() && arguments.At(0).As<ObjectWrapper>() != null )
  58. {
  59. var enumerable = arguments.At(0).As<ObjectWrapper>().Target as IEnumerable;
  60. if (enumerable != null)
  61. {
  62. var jsArray = Engine.Array.Construct(Arguments.Empty);
  63. foreach (var item in enumerable)
  64. {
  65. var jsItem = JsValue.FromObject(Engine, item);
  66. Engine.Array.PrototypeObject.Push(jsArray, Arguments.From(jsItem));
  67. }
  68. return jsArray;
  69. }
  70. }
  71. else
  72. {
  73. instance.FastAddProperty("length", 0, true, false, false);
  74. PrototypeObject.Push(instance, arguments);
  75. }
  76. return instance;
  77. }
  78. }
  79. }