SymbolPrototype.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using Jint.Collections;
  2. using Jint.Native.Object;
  3. using Jint.Runtime;
  4. using Jint.Runtime.Descriptors;
  5. using Jint.Runtime.Interop;
  6. namespace Jint.Native.Symbol
  7. {
  8. /// <summary>
  9. /// http://www.ecma-international.org/ecma-262/5.1/#sec-15.5.4
  10. /// </summary>
  11. public sealed class SymbolPrototype : ObjectInstance
  12. {
  13. private SymbolConstructor _symbolConstructor;
  14. private SymbolPrototype(Engine engine)
  15. : base(engine)
  16. {
  17. }
  18. public static SymbolPrototype CreatePrototypeObject(Engine engine, SymbolConstructor symbolConstructor)
  19. {
  20. var obj = new SymbolPrototype(engine)
  21. {
  22. _prototype = engine.Object.PrototypeObject,
  23. _symbolConstructor = symbolConstructor
  24. };
  25. return obj;
  26. }
  27. protected override void Initialize()
  28. {
  29. _properties = new StringDictionarySlim<PropertyDescriptor>(8)
  30. {
  31. ["length"] = PropertyDescriptor.AllForbiddenDescriptor.NumberZero,
  32. ["constructor"] = new PropertyDescriptor(_symbolConstructor, true, false, true),
  33. ["toString"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "toString", ToSymbolString), true, false, true),
  34. ["valueOf"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "valueOf", ValueOf), true, false, true),
  35. ["toStringTag"] = new PropertyDescriptor(new JsString("Symbol"), false, false, true),
  36. [GlobalSymbolRegistry.ToPrimitive] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "toPrimitive", ToPrimitive), false, false, true),
  37. [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor(new JsString("Symbol"), false, false, true)
  38. };
  39. }
  40. private string SymbolDescriptiveString(JsSymbol sym)
  41. {
  42. return $"Symbol({sym.AsSymbol()})";
  43. }
  44. private JsValue ToSymbolString(JsValue thisObject, JsValue[] arguments)
  45. {
  46. if (!thisObject.IsSymbol())
  47. {
  48. ExceptionHelper.ThrowTypeError(Engine);
  49. }
  50. return SymbolDescriptiveString((JsSymbol)thisObject);
  51. }
  52. private JsValue ValueOf(JsValue thisObject, JsValue[] arguments)
  53. {
  54. var sym = thisObject.TryCast<SymbolInstance>();
  55. if (ReferenceEquals(sym, null))
  56. {
  57. ExceptionHelper.ThrowTypeError(Engine);
  58. }
  59. return sym.SymbolData;
  60. }
  61. private JsValue ToPrimitive(JsValue thisObject, JsValue[] arguments)
  62. {
  63. if (thisObject.IsSymbol())
  64. {
  65. return thisObject;
  66. }
  67. // Steps 3. and 4.
  68. var o = thisObject.AsInstance<SymbolInstance>();
  69. if (ReferenceEquals(o, null))
  70. {
  71. ExceptionHelper.ThrowTypeError(Engine);
  72. }
  73. return o.SymbolData;
  74. }
  75. }
  76. }