SymbolPrototype.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. const PropertyFlag lengthFlags = PropertyFlag.Configurable;
  30. const PropertyFlag propertyFlags = PropertyFlag.Configurable;
  31. SetProperties(new PropertyDictionary(5, checkExistingKeys: false)
  32. {
  33. ["length"] = new PropertyDescriptor(JsNumber.PositiveZero, propertyFlags),
  34. ["constructor"] = new PropertyDescriptor(_symbolConstructor, PropertyFlag.Configurable | PropertyFlag.Writable),
  35. ["description"] = new GetSetPropertyDescriptor(new ClrFunctionInstance(Engine, "description", Description, 0, lengthFlags), Undefined, propertyFlags),
  36. ["toString"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "toString", ToSymbolString, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable),
  37. ["valueOf"] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "valueOf", ValueOf, 0, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable)
  38. });
  39. SetSymbols(new SymbolDictionary(1)
  40. {
  41. [GlobalSymbolRegistry.ToPrimitive] = new PropertyDescriptor(new ClrFunctionInstance(Engine, "[Symbol.toPrimitive]", ToPrimitive, 1, lengthFlags), propertyFlags), [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor(new JsString("Symbol"), propertyFlags)
  42. }
  43. );
  44. }
  45. private JsValue Description(JsValue thisObject, JsValue[] arguments)
  46. {
  47. var sym = ThisSymbolValue(thisObject);
  48. return sym._value;
  49. }
  50. private JsValue ToSymbolString(JsValue thisObject, JsValue[] arguments)
  51. {
  52. var sym = ThisSymbolValue(thisObject);
  53. return new JsString(SymbolDescriptiveString(sym));
  54. }
  55. private JsValue ValueOf(JsValue thisObject, JsValue[] arguments)
  56. {
  57. return ThisSymbolValue(thisObject);
  58. }
  59. private JsValue ToPrimitive(JsValue thisObject, JsValue[] arguments)
  60. {
  61. return ThisSymbolValue(thisObject);
  62. }
  63. private static string SymbolDescriptiveString(JsSymbol symbol) => symbol.ToString();
  64. private JsSymbol ThisSymbolValue(JsValue thisObject)
  65. {
  66. if (thisObject is JsSymbol s)
  67. {
  68. return s;
  69. }
  70. if (thisObject is SymbolInstance instance)
  71. {
  72. return instance.SymbolData;
  73. }
  74. return ExceptionHelper.ThrowTypeError<JsSymbol>(_engine);
  75. }
  76. }
  77. }