utils.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. "use strict";
  2. // Returns "Type(value) is Object" in ES terminology.
  3. function isObject(value) {
  4. return (typeof value === "object" && value !== null) || typeof value === "function";
  5. }
  6. const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
  7. // Like `Object.assign`, but using `[[GetOwnProperty]]` and `[[DefineOwnProperty]]`
  8. // instead of `[[Get]]` and `[[Set]]` and only allowing objects
  9. function define(target, source) {
  10. for (const key of Reflect.ownKeys(source)) {
  11. const descriptor = Reflect.getOwnPropertyDescriptor(source, key);
  12. if (descriptor && !Reflect.defineProperty(target, key, descriptor)) {
  13. throw new TypeError(`Cannot redefine property: ${String(key)}`);
  14. }
  15. }
  16. }
  17. function newObjectInRealm(globalObject, object) {
  18. const ctorRegistry = initCtorRegistry(globalObject);
  19. return Object.defineProperties(
  20. Object.create(ctorRegistry["%Object.prototype%"]),
  21. Object.getOwnPropertyDescriptors(object)
  22. );
  23. }
  24. const wrapperSymbol = Symbol("wrapper");
  25. const implSymbol = Symbol("impl");
  26. const sameObjectCaches = Symbol("SameObject caches");
  27. const ctorRegistrySymbol = Symbol.for("[webidl2js] constructor registry");
  28. const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
  29. function initCtorRegistry(globalObject) {
  30. if (hasOwn(globalObject, ctorRegistrySymbol)) {
  31. return globalObject[ctorRegistrySymbol];
  32. }
  33. const ctorRegistry = Object.create(null);
  34. // In addition to registering all the WebIDL2JS-generated types in the constructor registry,
  35. // we also register a few intrinsics that we make use of in generated code, since they are not
  36. // easy to grab from the globalObject variable.
  37. ctorRegistry["%Object.prototype%"] = globalObject.Object.prototype;
  38. ctorRegistry["%IteratorPrototype%"] = Object.getPrototypeOf(
  39. Object.getPrototypeOf(new globalObject.Array()[Symbol.iterator]())
  40. );
  41. try {
  42. ctorRegistry["%AsyncIteratorPrototype%"] = Object.getPrototypeOf(
  43. Object.getPrototypeOf(
  44. globalObject.eval("(async function* () {})").prototype
  45. )
  46. );
  47. } catch {
  48. ctorRegistry["%AsyncIteratorPrototype%"] = AsyncIteratorPrototype;
  49. }
  50. globalObject[ctorRegistrySymbol] = ctorRegistry;
  51. return ctorRegistry;
  52. }
  53. function getSameObject(wrapper, prop, creator) {
  54. if (!wrapper[sameObjectCaches]) {
  55. wrapper[sameObjectCaches] = Object.create(null);
  56. }
  57. if (prop in wrapper[sameObjectCaches]) {
  58. return wrapper[sameObjectCaches][prop];
  59. }
  60. wrapper[sameObjectCaches][prop] = creator();
  61. return wrapper[sameObjectCaches][prop];
  62. }
  63. function wrapperForImpl(impl) {
  64. return impl ? impl[wrapperSymbol] : null;
  65. }
  66. function implForWrapper(wrapper) {
  67. return wrapper ? wrapper[implSymbol] : null;
  68. }
  69. function tryWrapperForImpl(impl) {
  70. const wrapper = wrapperForImpl(impl);
  71. return wrapper ? wrapper : impl;
  72. }
  73. function tryImplForWrapper(wrapper) {
  74. const impl = implForWrapper(wrapper);
  75. return impl ? impl : wrapper;
  76. }
  77. const iterInternalSymbol = Symbol("internal");
  78. function isArrayIndexPropName(P) {
  79. if (typeof P !== "string") {
  80. return false;
  81. }
  82. const i = P >>> 0;
  83. if (i === 2 ** 32 - 1) {
  84. return false;
  85. }
  86. const s = `${i}`;
  87. if (P !== s) {
  88. return false;
  89. }
  90. return true;
  91. }
  92. const byteLengthGetter =
  93. Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
  94. function isArrayBuffer(value) {
  95. try {
  96. byteLengthGetter.call(value);
  97. return true;
  98. } catch (e) {
  99. return false;
  100. }
  101. }
  102. function iteratorResult([key, value], kind) {
  103. let result;
  104. switch (kind) {
  105. case "key":
  106. result = key;
  107. break;
  108. case "value":
  109. result = value;
  110. break;
  111. case "key+value":
  112. result = [key, value];
  113. break;
  114. }
  115. return { value: result, done: false };
  116. }
  117. const supportsPropertyIndex = Symbol("supports property index");
  118. const supportedPropertyIndices = Symbol("supported property indices");
  119. const supportsPropertyName = Symbol("supports property name");
  120. const supportedPropertyNames = Symbol("supported property names");
  121. const indexedGet = Symbol("indexed property get");
  122. const indexedSetNew = Symbol("indexed property set new");
  123. const indexedSetExisting = Symbol("indexed property set existing");
  124. const namedGet = Symbol("named property get");
  125. const namedSetNew = Symbol("named property set new");
  126. const namedSetExisting = Symbol("named property set existing");
  127. const namedDelete = Symbol("named property delete");
  128. const asyncIteratorNext = Symbol("async iterator get the next iteration result");
  129. const asyncIteratorReturn = Symbol("async iterator return steps");
  130. const asyncIteratorInit = Symbol("async iterator initialization steps");
  131. const asyncIteratorEOI = Symbol("async iterator end of iteration");
  132. module.exports = exports = {
  133. isObject,
  134. hasOwn,
  135. define,
  136. newObjectInRealm,
  137. wrapperSymbol,
  138. implSymbol,
  139. getSameObject,
  140. ctorRegistrySymbol,
  141. initCtorRegistry,
  142. wrapperForImpl,
  143. implForWrapper,
  144. tryWrapperForImpl,
  145. tryImplForWrapper,
  146. iterInternalSymbol,
  147. isArrayBuffer,
  148. isArrayIndexPropName,
  149. supportsPropertyIndex,
  150. supportedPropertyIndices,
  151. supportsPropertyName,
  152. supportedPropertyNames,
  153. indexedGet,
  154. indexedSetNew,
  155. indexedSetExisting,
  156. namedGet,
  157. namedSetNew,
  158. namedSetExisting,
  159. namedDelete,
  160. asyncIteratorNext,
  161. asyncIteratorReturn,
  162. asyncIteratorInit,
  163. asyncIteratorEOI,
  164. iteratorResult
  165. };