ObjectPrototype.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using System;
  2. using Jint.Runtime;
  3. using Jint.Runtime.Descriptors;
  4. using Jint.Runtime.Interop;
  5. namespace Jint.Native.Object
  6. {
  7. public sealed class ObjectPrototype : ObjectInstance
  8. {
  9. private ObjectPrototype(Engine engine) : base(engine)
  10. {
  11. }
  12. public static ObjectPrototype CreatePrototypeObject(Engine engine, ObjectConstructor objectConstructor)
  13. {
  14. var obj = new ObjectPrototype(engine) { Extensible = true };
  15. obj.FastAddProperty("constructor", objectConstructor, false, false, false);
  16. return obj;
  17. }
  18. public void Configure()
  19. {
  20. FastAddProperty("toString", new ClrFunctionInstance<object, string>(Engine, ToString), true, false, true);
  21. FastAddProperty("toLocaleString", new ClrFunctionInstance<object, object>(Engine, ToLocaleString), true, false, true);
  22. FastAddProperty("valueOf", new ClrFunctionInstance<object, object>(Engine, ValueOf), true, false, true);
  23. FastAddProperty("hasOwnProperty", new ClrFunctionInstance<object, bool>(Engine, HasOwnProperty), true, false, true);
  24. FastAddProperty("isPrototypeOf", new ClrFunctionInstance<object, bool>(Engine, IsPrototypeOf), true, false, true);
  25. FastAddProperty("propertyIsEnumerable", new ClrFunctionInstance<object, bool>(Engine, PropertyIsEnumerable), true, false, true);
  26. }
  27. private bool PropertyIsEnumerable(object thisObject, object[] arguments)
  28. {
  29. var p = TypeConverter.ToString(arguments[0]);
  30. var o = TypeConverter.ToObject(Engine, thisObject);
  31. var desc = o.GetOwnProperty(p);
  32. if (desc == PropertyDescriptor.Undefined)
  33. {
  34. return false;
  35. }
  36. return desc.Enumerable;
  37. }
  38. private object ValueOf(object thisObject, object[] arguments)
  39. {
  40. var o = TypeConverter.ToObject(Engine, thisObject);
  41. return o;
  42. }
  43. private bool IsPrototypeOf(object thisObject, object[] arguments)
  44. {
  45. var v = arguments[0] as ObjectInstance;
  46. if (v == null)
  47. {
  48. return false;
  49. }
  50. var o = TypeConverter.ToObject(Engine, thisObject);
  51. while (true)
  52. {
  53. v = v.Prototype;
  54. if (v == null)
  55. {
  56. return false;
  57. }
  58. if (o == v)
  59. {
  60. return true;
  61. }
  62. }
  63. }
  64. private object ToLocaleString(object thisObject, object[] arguments)
  65. {
  66. var o = TypeConverter.ToObject(Engine, thisObject);
  67. var toString = o.Get("toString") as ICallable;
  68. if (toString == null)
  69. {
  70. throw new JavaScriptException(Engine.TypeError);
  71. }
  72. return toString.Call(o, Arguments.Empty);
  73. }
  74. /// <summary>
  75. /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4.2
  76. /// </summary>
  77. /// <param name="thisObject"></param>
  78. /// <param name="arguments"></param>
  79. /// <returns></returns>
  80. public string ToString(object thisObject, object[] arguments)
  81. {
  82. if (thisObject == Undefined.Instance)
  83. {
  84. return "[object Undefined]";
  85. }
  86. if (thisObject == Null.Instance)
  87. {
  88. return "[object Null]";
  89. }
  90. var o = TypeConverter.ToObject(Engine, thisObject);
  91. return "[object " + o.Class + "]";
  92. }
  93. /// <summary>
  94. /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4.5
  95. /// </summary>
  96. /// <param name="thisObject"></param>
  97. /// <param name="arguments"></param>
  98. /// <returns></returns>
  99. public bool HasOwnProperty(object thisObject, object[] arguments)
  100. {
  101. var p = TypeConverter.ToString(arguments[0]);
  102. var o = TypeConverter.ToObject(Engine, thisObject);
  103. var desc = o.GetOwnProperty(p);
  104. return desc != PropertyDescriptor.Undefined;
  105. }
  106. }
  107. }