You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1466 lines
47 KiB

4 years ago
  1. 'use strict';
  2. var has = require('has');
  3. var toPrimitive = require('es-to-primitive/es6');
  4. var keys = require('object-keys');
  5. var inspect = require('object-inspect');
  6. var GetIntrinsic = require('./GetIntrinsic');
  7. var $TypeError = GetIntrinsic('%TypeError%');
  8. var $RangeError = GetIntrinsic('%RangeError%');
  9. var $SyntaxError = GetIntrinsic('%SyntaxError%');
  10. var $Array = GetIntrinsic('%Array%');
  11. var $ArrayPrototype = $Array.prototype;
  12. var $String = GetIntrinsic('%String%');
  13. var $Object = GetIntrinsic('%Object%');
  14. var $Number = GetIntrinsic('%Number%');
  15. var $Symbol = GetIntrinsic('%Symbol%', true);
  16. var $RegExp = GetIntrinsic('%RegExp%');
  17. var $Date = GetIntrinsic('%Date%');
  18. var $Function = GetIntrinsic('%Function%');
  19. var $preventExtensions = $Object.preventExtensions;
  20. var hasSymbols = require('has-symbols')();
  21. var assertRecord = require('./helpers/assertRecord');
  22. var $isNaN = require('./helpers/isNaN');
  23. var $isFinite = require('./helpers/isFinite');
  24. var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1;
  25. var MAX_SAFE_INTEGER = require('./helpers/maxSafeInteger');
  26. var assign = require('./helpers/assign');
  27. var sign = require('./helpers/sign');
  28. var mod = require('./helpers/mod');
  29. var isPrimitive = require('./helpers/isPrimitive');
  30. var forEach = require('./helpers/forEach');
  31. var every = require('./helpers/every');
  32. var isSamePropertyDescriptor = require('./helpers/isSamePropertyDescriptor');
  33. var isPropertyDescriptor = require('./helpers/isPropertyDescriptor');
  34. var parseInteger = parseInt;
  35. var callBound = require('./helpers/callBound');
  36. var regexTester = require('./helpers/regexTester');
  37. var getIteratorMethod = require('./helpers/getIteratorMethod');
  38. var getSymbolDescription = require('./helpers/getSymbolDescription');
  39. var $PromiseThen = callBound('Promise.prototype.then', true);
  40. var arraySlice = callBound('Array.prototype.slice');
  41. var strSlice = callBound('String.prototype.slice');
  42. var $indexOf = callBound('Array.prototype.indexOf');
  43. var $push = callBound('Array.prototype.push');
  44. var isBinary = regexTester(/^0b[01]+$/i);
  45. var isOctal = regexTester(/^0o[0-7]+$/i);
  46. var isDigit = regexTester(/^[0-9]$/);
  47. var regexExec = callBound('RegExp.prototype.exec');
  48. var nonWS = ['\u0085', '\u200b', '\ufffe'].join('');
  49. var nonWSregex = new $RegExp('[' + nonWS + ']', 'g');
  50. var hasNonWS = regexTester(nonWSregex);
  51. var isInvalidHexLiteral = regexTester(/^[-+]0x[0-9a-f]+$/i);
  52. var $charCodeAt = callBound('String.prototype.charCodeAt');
  53. var $isEnumerable = callBound('Object.prototype.propertyIsEnumerable');
  54. var toStr = callBound('Object.prototype.toString');
  55. var $NumberValueOf = callBound('Number.prototype.valueOf');
  56. var $BooleanValueOf = callBound('Boolean.prototype.valueOf');
  57. var $StringValueOf = callBound('String.prototype.valueOf');
  58. var $DateValueOf = callBound('Date.prototype.valueOf');
  59. var $SymbolToString = callBound('Symbol.prototype.toString', true);
  60. var $floor = Math.floor;
  61. var $abs = Math.abs;
  62. var $ObjectCreate = $Object.create;
  63. var $gOPD = $Object.getOwnPropertyDescriptor;
  64. var $gOPN = $Object.getOwnPropertyNames;
  65. var $gOPS = $Object.getOwnPropertySymbols;
  66. var $isExtensible = $Object.isExtensible;
  67. var $defineProperty = $Object.defineProperty;
  68. var $setProto = require('./helpers/setProto');
  69. var DefineOwnProperty = function DefineOwnProperty(ES, O, P, desc) {
  70. if (!$defineProperty) {
  71. if (!ES.IsDataDescriptor(desc)) {
  72. // ES3 does not support getters/setters
  73. return false;
  74. }
  75. if (!desc['[[Configurable]]'] || !desc['[[Writable]]']) {
  76. return false;
  77. }
  78. // fallback for ES3
  79. if (P in O && $isEnumerable(O, P) !== !!desc['[[Enumerable]]']) {
  80. // a non-enumerable existing property
  81. return false;
  82. }
  83. // property does not exist at all, or exists but is enumerable
  84. var V = desc['[[Value]]'];
  85. // eslint-disable-next-line no-param-reassign
  86. O[P] = V; // will use [[Define]]
  87. return ES.SameValue(O[P], V);
  88. }
  89. $defineProperty(O, P, ES.FromPropertyDescriptor(desc));
  90. return true;
  91. };
  92. // whitespace from: https://es5.github.io/#x15.5.4.20
  93. // implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
  94. var ws = [
  95. '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003',
  96. '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028',
  97. '\u2029\uFEFF'
  98. ].join('');
  99. var trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');
  100. var $replace = callBound('String.prototype.replace');
  101. var trim = function (value) {
  102. return $replace(value, trimRegex, '');
  103. };
  104. var ES5 = require('./es5');
  105. var hasRegExpMatcher = require('is-regex');
  106. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-abstract-operations
  107. var ES6 = assign(assign({}, ES5), {
  108. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-call-f-v-args
  109. Call: function Call(F, V) {
  110. var args = arguments.length > 2 ? arguments[2] : [];
  111. if (!this.IsCallable(F)) {
  112. throw new $TypeError(inspect(F) + ' is not a function');
  113. }
  114. return F.apply(V, args);
  115. },
  116. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toprimitive
  117. ToPrimitive: toPrimitive,
  118. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toboolean
  119. // ToBoolean: ES5.ToBoolean,
  120. // https://ecma-international.org/ecma-262/6.0/#sec-tonumber
  121. ToNumber: function ToNumber(argument) {
  122. var value = isPrimitive(argument) ? argument : toPrimitive(argument, $Number);
  123. if (typeof value === 'symbol') {
  124. throw new $TypeError('Cannot convert a Symbol value to a number');
  125. }
  126. if (typeof value === 'string') {
  127. if (isBinary(value)) {
  128. return this.ToNumber(parseInteger(strSlice(value, 2), 2));
  129. } else if (isOctal(value)) {
  130. return this.ToNumber(parseInteger(strSlice(value, 2), 8));
  131. } else if (hasNonWS(value) || isInvalidHexLiteral(value)) {
  132. return NaN;
  133. } else {
  134. var trimmed = trim(value);
  135. if (trimmed !== value) {
  136. return this.ToNumber(trimmed);
  137. }
  138. }
  139. }
  140. return $Number(value);
  141. },
  142. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tointeger
  143. // ToInteger: ES5.ToNumber,
  144. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint32
  145. // ToInt32: ES5.ToInt32,
  146. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint32
  147. // ToUint32: ES5.ToUint32,
  148. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint16
  149. ToInt16: function ToInt16(argument) {
  150. var int16bit = this.ToUint16(argument);
  151. return int16bit >= 0x8000 ? int16bit - 0x10000 : int16bit;
  152. },
  153. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint16
  154. // ToUint16: ES5.ToUint16,
  155. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint8
  156. ToInt8: function ToInt8(argument) {
  157. var int8bit = this.ToUint8(argument);
  158. return int8bit >= 0x80 ? int8bit - 0x100 : int8bit;
  159. },
  160. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint8
  161. ToUint8: function ToUint8(argument) {
  162. var number = this.ToNumber(argument);
  163. if ($isNaN(number) || number === 0 || !$isFinite(number)) { return 0; }
  164. var posInt = sign(number) * $floor($abs(number));
  165. return mod(posInt, 0x100);
  166. },
  167. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint8clamp
  168. ToUint8Clamp: function ToUint8Clamp(argument) {
  169. var number = this.ToNumber(argument);
  170. if ($isNaN(number) || number <= 0) { return 0; }
  171. if (number >= 0xFF) { return 0xFF; }
  172. var f = $floor(argument);
  173. if (f + 0.5 < number) { return f + 1; }
  174. if (number < f + 0.5) { return f; }
  175. if (f % 2 !== 0) { return f + 1; }
  176. return f;
  177. },
  178. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tostring
  179. ToString: function ToString(argument) {
  180. if (typeof argument === 'symbol') {
  181. throw new $TypeError('Cannot convert a Symbol value to a string');
  182. }
  183. return $String(argument);
  184. },
  185. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toobject
  186. ToObject: function ToObject(value) {
  187. this.RequireObjectCoercible(value);
  188. return $Object(value);
  189. },
  190. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-topropertykey
  191. ToPropertyKey: function ToPropertyKey(argument) {
  192. var key = this.ToPrimitive(argument, $String);
  193. return typeof key === 'symbol' ? key : this.ToString(key);
  194. },
  195. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
  196. ToLength: function ToLength(argument) {
  197. var len = this.ToInteger(argument);
  198. if (len <= 0) { return 0; } // includes converting -0 to +0
  199. if (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }
  200. return len;
  201. },
  202. // https://ecma-international.org/ecma-262/6.0/#sec-canonicalnumericindexstring
  203. CanonicalNumericIndexString: function CanonicalNumericIndexString(argument) {
  204. if (toStr(argument) !== '[object String]') {
  205. throw new $TypeError('must be a string');
  206. }
  207. if (argument === '-0') { return -0; }
  208. var n = this.ToNumber(argument);
  209. if (this.SameValue(this.ToString(n), argument)) { return n; }
  210. return void 0;
  211. },
  212. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-requireobjectcoercible
  213. RequireObjectCoercible: ES5.CheckObjectCoercible,
  214. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isarray
  215. IsArray: $Array.isArray || function IsArray(argument) {
  216. return toStr(argument) === '[object Array]';
  217. },
  218. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-iscallable
  219. // IsCallable: ES5.IsCallable,
  220. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isconstructor
  221. IsConstructor: function IsConstructor(argument) {
  222. return typeof argument === 'function' && !!argument.prototype; // unfortunately there's no way to truly check this without try/catch `new argument` or Proxy
  223. },
  224. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isextensible-o
  225. IsExtensible: $preventExtensions
  226. ? function IsExtensible(obj) {
  227. if (isPrimitive(obj)) {
  228. return false;
  229. }
  230. return $isExtensible(obj);
  231. }
  232. : function isExtensible(obj) { return true; }, // eslint-disable-line no-unused-vars
  233. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isinteger
  234. IsInteger: function IsInteger(argument) {
  235. if (typeof argument !== 'number' || $isNaN(argument) || !$isFinite(argument)) {
  236. return false;
  237. }
  238. var abs = $abs(argument);
  239. return $floor(abs) === abs;
  240. },
  241. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ispropertykey
  242. IsPropertyKey: function IsPropertyKey(argument) {
  243. return typeof argument === 'string' || typeof argument === 'symbol';
  244. },
  245. // https://ecma-international.org/ecma-262/6.0/#sec-isregexp
  246. IsRegExp: function IsRegExp(argument) {
  247. if (!argument || typeof argument !== 'object') {
  248. return false;
  249. }
  250. if (hasSymbols) {
  251. var isRegExp = argument[$Symbol.match];
  252. if (typeof isRegExp !== 'undefined') {
  253. return ES5.ToBoolean(isRegExp);
  254. }
  255. }
  256. return hasRegExpMatcher(argument);
  257. },
  258. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue
  259. // SameValue: ES5.SameValue,
  260. // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero
  261. SameValueZero: function SameValueZero(x, y) {
  262. return (x === y) || ($isNaN(x) && $isNaN(y));
  263. },
  264. /**
  265. * 7.3.2 GetV (V, P)
  266. * 1. Assert: IsPropertyKey(P) is true.
  267. * 2. Let O be ToObject(V).
  268. * 3. ReturnIfAbrupt(O).
  269. * 4. Return O.[[Get]](P, V).
  270. */
  271. GetV: function GetV(V, P) {
  272. // 7.3.2.1
  273. if (!this.IsPropertyKey(P)) {
  274. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  275. }
  276. // 7.3.2.2-3
  277. var O = this.ToObject(V);
  278. // 7.3.2.4
  279. return O[P];
  280. },
  281. /**
  282. * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod
  283. * 1. Assert: IsPropertyKey(P) is true.
  284. * 2. Let func be GetV(O, P).
  285. * 3. ReturnIfAbrupt(func).
  286. * 4. If func is either undefined or null, return undefined.
  287. * 5. If IsCallable(func) is false, throw a TypeError exception.
  288. * 6. Return func.
  289. */
  290. GetMethod: function GetMethod(O, P) {
  291. // 7.3.9.1
  292. if (!this.IsPropertyKey(P)) {
  293. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  294. }
  295. // 7.3.9.2
  296. var func = this.GetV(O, P);
  297. // 7.3.9.4
  298. if (func == null) {
  299. return void 0;
  300. }
  301. // 7.3.9.5
  302. if (!this.IsCallable(func)) {
  303. throw new $TypeError(P + 'is not a function');
  304. }
  305. // 7.3.9.6
  306. return func;
  307. },
  308. /**
  309. * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p
  310. * 1. Assert: Type(O) is Object.
  311. * 2. Assert: IsPropertyKey(P) is true.
  312. * 3. Return O.[[Get]](P, O).
  313. */
  314. Get: function Get(O, P) {
  315. // 7.3.1.1
  316. if (this.Type(O) !== 'Object') {
  317. throw new $TypeError('Assertion failed: Type(O) is not Object');
  318. }
  319. // 7.3.1.2
  320. if (!this.IsPropertyKey(P)) {
  321. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true, got ' + inspect(P));
  322. }
  323. // 7.3.1.3
  324. return O[P];
  325. },
  326. Type: function Type(x) {
  327. if (typeof x === 'symbol') {
  328. return 'Symbol';
  329. }
  330. return ES5.Type(x);
  331. },
  332. // https://ecma-international.org/ecma-262/6.0/#sec-speciesconstructor
  333. SpeciesConstructor: function SpeciesConstructor(O, defaultConstructor) {
  334. if (this.Type(O) !== 'Object') {
  335. throw new $TypeError('Assertion failed: Type(O) is not Object');
  336. }
  337. var C = O.constructor;
  338. if (typeof C === 'undefined') {
  339. return defaultConstructor;
  340. }
  341. if (this.Type(C) !== 'Object') {
  342. throw new $TypeError('O.constructor is not an Object');
  343. }
  344. var S = hasSymbols && $Symbol.species ? C[$Symbol.species] : void 0;
  345. if (S == null) {
  346. return defaultConstructor;
  347. }
  348. if (this.IsConstructor(S)) {
  349. return S;
  350. }
  351. throw new $TypeError('no constructor found');
  352. },
  353. // https://www.ecma-international.org/ecma-262/6.0/#sec-frompropertydescriptor
  354. FromPropertyDescriptor: function FromPropertyDescriptor(Desc) {
  355. if (typeof Desc === 'undefined') {
  356. return Desc;
  357. }
  358. assertRecord(this, 'Property Descriptor', 'Desc', Desc);
  359. var obj = {};
  360. if ('[[Value]]' in Desc) {
  361. obj.value = Desc['[[Value]]'];
  362. }
  363. if ('[[Writable]]' in Desc) {
  364. obj.writable = Desc['[[Writable]]'];
  365. }
  366. if ('[[Get]]' in Desc) {
  367. obj.get = Desc['[[Get]]'];
  368. }
  369. if ('[[Set]]' in Desc) {
  370. obj.set = Desc['[[Set]]'];
  371. }
  372. if ('[[Enumerable]]' in Desc) {
  373. obj.enumerable = Desc['[[Enumerable]]'];
  374. }
  375. if ('[[Configurable]]' in Desc) {
  376. obj.configurable = Desc['[[Configurable]]'];
  377. }
  378. return obj;
  379. },
  380. // https://ecma-international.org/ecma-262/6.0/#sec-completepropertydescriptor
  381. CompletePropertyDescriptor: function CompletePropertyDescriptor(Desc) {
  382. /* eslint no-param-reassign: 0 */
  383. assertRecord(this, 'Property Descriptor', 'Desc', Desc);
  384. if (this.IsGenericDescriptor(Desc) || this.IsDataDescriptor(Desc)) {
  385. if (!has(Desc, '[[Value]]')) {
  386. Desc['[[Value]]'] = void 0;
  387. }
  388. if (!has(Desc, '[[Writable]]')) {
  389. Desc['[[Writable]]'] = false;
  390. }
  391. } else {
  392. if (!has(Desc, '[[Get]]')) {
  393. Desc['[[Get]]'] = void 0;
  394. }
  395. if (!has(Desc, '[[Set]]')) {
  396. Desc['[[Set]]'] = void 0;
  397. }
  398. }
  399. if (!has(Desc, '[[Enumerable]]')) {
  400. Desc['[[Enumerable]]'] = false;
  401. }
  402. if (!has(Desc, '[[Configurable]]')) {
  403. Desc['[[Configurable]]'] = false;
  404. }
  405. return Desc;
  406. },
  407. // https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw
  408. Set: function Set(O, P, V, Throw) {
  409. if (this.Type(O) !== 'Object') {
  410. throw new $TypeError('O must be an Object');
  411. }
  412. if (!this.IsPropertyKey(P)) {
  413. throw new $TypeError('P must be a Property Key');
  414. }
  415. if (this.Type(Throw) !== 'Boolean') {
  416. throw new $TypeError('Throw must be a Boolean');
  417. }
  418. if (Throw) {
  419. O[P] = V;
  420. return true;
  421. } else {
  422. try {
  423. O[P] = V;
  424. } catch (e) {
  425. return false;
  426. }
  427. }
  428. },
  429. // https://ecma-international.org/ecma-262/6.0/#sec-hasownproperty
  430. HasOwnProperty: function HasOwnProperty(O, P) {
  431. if (this.Type(O) !== 'Object') {
  432. throw new $TypeError('O must be an Object');
  433. }
  434. if (!this.IsPropertyKey(P)) {
  435. throw new $TypeError('P must be a Property Key');
  436. }
  437. return has(O, P);
  438. },
  439. // https://ecma-international.org/ecma-262/6.0/#sec-hasproperty
  440. HasProperty: function HasProperty(O, P) {
  441. if (this.Type(O) !== 'Object') {
  442. throw new $TypeError('O must be an Object');
  443. }
  444. if (!this.IsPropertyKey(P)) {
  445. throw new $TypeError('P must be a Property Key');
  446. }
  447. return P in O;
  448. },
  449. // https://ecma-international.org/ecma-262/6.0/#sec-isconcatspreadable
  450. IsConcatSpreadable: function IsConcatSpreadable(O) {
  451. if (this.Type(O) !== 'Object') {
  452. return false;
  453. }
  454. if (hasSymbols && typeof $Symbol.isConcatSpreadable === 'symbol') {
  455. var spreadable = this.Get(O, Symbol.isConcatSpreadable);
  456. if (typeof spreadable !== 'undefined') {
  457. return this.ToBoolean(spreadable);
  458. }
  459. }
  460. return this.IsArray(O);
  461. },
  462. // https://ecma-international.org/ecma-262/6.0/#sec-invoke
  463. Invoke: function Invoke(O, P) {
  464. if (!this.IsPropertyKey(P)) {
  465. throw new $TypeError('P must be a Property Key');
  466. }
  467. var argumentsList = arraySlice(arguments, 2);
  468. var func = this.GetV(O, P);
  469. return this.Call(func, O, argumentsList);
  470. },
  471. // https://ecma-international.org/ecma-262/6.0/#sec-getiterator
  472. GetIterator: function GetIterator(obj, method) {
  473. var actualMethod = method;
  474. if (arguments.length < 2) {
  475. actualMethod = getIteratorMethod(this, obj);
  476. }
  477. var iterator = this.Call(actualMethod, obj);
  478. if (this.Type(iterator) !== 'Object') {
  479. throw new $TypeError('iterator must return an object');
  480. }
  481. return iterator;
  482. },
  483. // https://ecma-international.org/ecma-262/6.0/#sec-iteratornext
  484. IteratorNext: function IteratorNext(iterator, value) {
  485. var result = this.Invoke(iterator, 'next', arguments.length < 2 ? [] : [value]);
  486. if (this.Type(result) !== 'Object') {
  487. throw new $TypeError('iterator next must return an object');
  488. }
  489. return result;
  490. },
  491. // https://ecma-international.org/ecma-262/6.0/#sec-iteratorcomplete
  492. IteratorComplete: function IteratorComplete(iterResult) {
  493. if (this.Type(iterResult) !== 'Object') {
  494. throw new $TypeError('Assertion failed: Type(iterResult) is not Object');
  495. }
  496. return this.ToBoolean(this.Get(iterResult, 'done'));
  497. },
  498. // https://ecma-international.org/ecma-262/6.0/#sec-iteratorvalue
  499. IteratorValue: function IteratorValue(iterResult) {
  500. if (this.Type(iterResult) !== 'Object') {
  501. throw new $TypeError('Assertion failed: Type(iterResult) is not Object');
  502. }
  503. return this.Get(iterResult, 'value');
  504. },
  505. // https://ecma-international.org/ecma-262/6.0/#sec-iteratorstep
  506. IteratorStep: function IteratorStep(iterator) {
  507. var result = this.IteratorNext(iterator);
  508. var done = this.IteratorComplete(result);
  509. return done === true ? false : result;
  510. },
  511. // https://ecma-international.org/ecma-262/6.0/#sec-iteratorclose
  512. IteratorClose: function IteratorClose(iterator, completion) {
  513. if (this.Type(iterator) !== 'Object') {
  514. throw new $TypeError('Assertion failed: Type(iterator) is not Object');
  515. }
  516. if (!this.IsCallable(completion)) {
  517. throw new $TypeError('Assertion failed: completion is not a thunk for a Completion Record');
  518. }
  519. var completionThunk = completion;
  520. var iteratorReturn = this.GetMethod(iterator, 'return');
  521. if (typeof iteratorReturn === 'undefined') {
  522. return completionThunk();
  523. }
  524. var completionRecord;
  525. try {
  526. var innerResult = this.Call(iteratorReturn, iterator, []);
  527. } catch (e) {
  528. // if we hit here, then "e" is the innerResult completion that needs re-throwing
  529. // if the completion is of type "throw", this will throw.
  530. completionRecord = completionThunk();
  531. completionThunk = null; // ensure it's not called twice.
  532. // if not, then return the innerResult completion
  533. throw e;
  534. }
  535. completionRecord = completionThunk(); // if innerResult worked, then throw if the completion does
  536. completionThunk = null; // ensure it's not called twice.
  537. if (this.Type(innerResult) !== 'Object') {
  538. throw new $TypeError('iterator .return must return an object');
  539. }
  540. return completionRecord;
  541. },
  542. // https://ecma-international.org/ecma-262/6.0/#sec-createiterresultobject
  543. CreateIterResultObject: function CreateIterResultObject(value, done) {
  544. if (this.Type(done) !== 'Boolean') {
  545. throw new $TypeError('Assertion failed: Type(done) is not Boolean');
  546. }
  547. return {
  548. value: value,
  549. done: done
  550. };
  551. },
  552. // https://ecma-international.org/ecma-262/6.0/#sec-regexpexec
  553. RegExpExec: function RegExpExec(R, S) {
  554. if (this.Type(R) !== 'Object') {
  555. throw new $TypeError('R must be an Object');
  556. }
  557. if (this.Type(S) !== 'String') {
  558. throw new $TypeError('S must be a String');
  559. }
  560. var exec = this.Get(R, 'exec');
  561. if (this.IsCallable(exec)) {
  562. var result = this.Call(exec, R, [S]);
  563. if (result === null || this.Type(result) === 'Object') {
  564. return result;
  565. }
  566. throw new $TypeError('"exec" method must return `null` or an Object');
  567. }
  568. return regexExec(R, S);
  569. },
  570. // https://ecma-international.org/ecma-262/6.0/#sec-arrayspeciescreate
  571. ArraySpeciesCreate: function ArraySpeciesCreate(originalArray, length) {
  572. if (!this.IsInteger(length) || length < 0) {
  573. throw new $TypeError('Assertion failed: length must be an integer >= 0');
  574. }
  575. var len = length === 0 ? 0 : length;
  576. var C;
  577. var isArray = this.IsArray(originalArray);
  578. if (isArray) {
  579. C = this.Get(originalArray, 'constructor');
  580. // TODO: figure out how to make a cross-realm normal Array, a same-realm Array
  581. // if (this.IsConstructor(C)) {
  582. // if C is another realm's Array, C = undefined
  583. // Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Array))) === null ?
  584. // }
  585. if (this.Type(C) === 'Object' && hasSymbols && $Symbol.species) {
  586. C = this.Get(C, $Symbol.species);
  587. if (C === null) {
  588. C = void 0;
  589. }
  590. }
  591. }
  592. if (typeof C === 'undefined') {
  593. return $Array(len);
  594. }
  595. if (!this.IsConstructor(C)) {
  596. throw new $TypeError('C must be a constructor');
  597. }
  598. return new C(len); // this.Construct(C, len);
  599. },
  600. CreateDataProperty: function CreateDataProperty(O, P, V) {
  601. if (this.Type(O) !== 'Object') {
  602. throw new $TypeError('Assertion failed: Type(O) is not Object');
  603. }
  604. if (!this.IsPropertyKey(P)) {
  605. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  606. }
  607. var oldDesc = $gOPD(O, P);
  608. var extensible = oldDesc || this.IsExtensible(O);
  609. var immutable = oldDesc && (!oldDesc.writable || !oldDesc.configurable);
  610. if (immutable || !extensible) {
  611. return false;
  612. }
  613. return DefineOwnProperty(this, O, P, {
  614. '[[Configurable]]': true,
  615. '[[Enumerable]]': true,
  616. '[[Value]]': V,
  617. '[[Writable]]': true
  618. });
  619. },
  620. // https://ecma-international.org/ecma-262/6.0/#sec-createdatapropertyorthrow
  621. CreateDataPropertyOrThrow: function CreateDataPropertyOrThrow(O, P, V) {
  622. if (this.Type(O) !== 'Object') {
  623. throw new $TypeError('Assertion failed: Type(O) is not Object');
  624. }
  625. if (!this.IsPropertyKey(P)) {
  626. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  627. }
  628. var success = this.CreateDataProperty(O, P, V);
  629. if (!success) {
  630. throw new $TypeError('unable to create data property');
  631. }
  632. return success;
  633. },
  634. // https://www.ecma-international.org/ecma-262/6.0/#sec-objectcreate
  635. ObjectCreate: function ObjectCreate(proto, internalSlotsList) {
  636. if (proto !== null && this.Type(proto) !== 'Object') {
  637. throw new $TypeError('Assertion failed: proto must be null or an object');
  638. }
  639. var slots = arguments.length < 2 ? [] : internalSlotsList;
  640. if (slots.length > 0) {
  641. throw new $SyntaxError('es-abstract does not yet support internal slots');
  642. }
  643. if (proto === null && !$ObjectCreate) {
  644. throw new $SyntaxError('native Object.create support is required to create null objects');
  645. }
  646. return $ObjectCreate(proto);
  647. },
  648. // https://ecma-international.org/ecma-262/6.0/#sec-advancestringindex
  649. AdvanceStringIndex: function AdvanceStringIndex(S, index, unicode) {
  650. if (this.Type(S) !== 'String') {
  651. throw new $TypeError('S must be a String');
  652. }
  653. if (!this.IsInteger(index) || index < 0 || index > MAX_SAFE_INTEGER) {
  654. throw new $TypeError('Assertion failed: length must be an integer >= 0 and <= 2**53');
  655. }
  656. if (this.Type(unicode) !== 'Boolean') {
  657. throw new $TypeError('Assertion failed: unicode must be a Boolean');
  658. }
  659. if (!unicode) {
  660. return index + 1;
  661. }
  662. var length = S.length;
  663. if ((index + 1) >= length) {
  664. return index + 1;
  665. }
  666. var first = $charCodeAt(S, index);
  667. if (first < 0xD800 || first > 0xDBFF) {
  668. return index + 1;
  669. }
  670. var second = $charCodeAt(S, index + 1);
  671. if (second < 0xDC00 || second > 0xDFFF) {
  672. return index + 1;
  673. }
  674. return index + 2;
  675. },
  676. // https://www.ecma-international.org/ecma-262/6.0/#sec-createmethodproperty
  677. CreateMethodProperty: function CreateMethodProperty(O, P, V) {
  678. if (this.Type(O) !== 'Object') {
  679. throw new $TypeError('Assertion failed: Type(O) is not Object');
  680. }
  681. if (!this.IsPropertyKey(P)) {
  682. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  683. }
  684. var newDesc = {
  685. '[[Configurable]]': true,
  686. '[[Enumerable]]': false,
  687. '[[Value]]': V,
  688. '[[Writable]]': true
  689. };
  690. return DefineOwnProperty(this, O, P, newDesc);
  691. },
  692. // https://www.ecma-international.org/ecma-262/6.0/#sec-definepropertyorthrow
  693. DefinePropertyOrThrow: function DefinePropertyOrThrow(O, P, desc) {
  694. if (this.Type(O) !== 'Object') {
  695. throw new $TypeError('Assertion failed: Type(O) is not Object');
  696. }
  697. if (!this.IsPropertyKey(P)) {
  698. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  699. }
  700. var Desc = isPropertyDescriptor(this, desc) ? desc : this.ToPropertyDescriptor(desc);
  701. if (!isPropertyDescriptor(this, Desc)) {
  702. throw new $TypeError('Assertion failed: Desc is not a valid Property Descriptor');
  703. }
  704. return DefineOwnProperty(this, O, P, Desc);
  705. },
  706. // https://www.ecma-international.org/ecma-262/6.0/#sec-deletepropertyorthrow
  707. DeletePropertyOrThrow: function DeletePropertyOrThrow(O, P) {
  708. if (this.Type(O) !== 'Object') {
  709. throw new $TypeError('Assertion failed: Type(O) is not Object');
  710. }
  711. if (!this.IsPropertyKey(P)) {
  712. throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
  713. }
  714. var success = delete O[P];
  715. if (!success) {
  716. throw new TypeError('Attempt to delete property failed.');
  717. }
  718. return success;
  719. },
  720. // https://www.ecma-international.org/ecma-262/6.0/#sec-enumerableownnames
  721. EnumerableOwnNames: function EnumerableOwnNames(O) {
  722. if (this.Type(O) !== 'Object') {
  723. throw new $TypeError('Assertion failed: Type(O) is not Object');
  724. }
  725. return keys(O);
  726. },
  727. // https://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-number-prototype-object
  728. thisNumberValue: function thisNumberValue(value) {
  729. if (this.Type(value) === 'Number') {
  730. return value;
  731. }
  732. return $NumberValueOf(value);
  733. },
  734. // https://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-boolean-prototype-object
  735. thisBooleanValue: function thisBooleanValue(value) {
  736. if (this.Type(value) === 'Boolean') {
  737. return value;
  738. }
  739. return $BooleanValueOf(value);
  740. },
  741. // https://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-string-prototype-object
  742. thisStringValue: function thisStringValue(value) {
  743. if (this.Type(value) === 'String') {
  744. return value;
  745. }
  746. return $StringValueOf(value);
  747. },
  748. // https://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-date-prototype-object
  749. thisTimeValue: function thisTimeValue(value) {
  750. return $DateValueOf(value);
  751. },
  752. // https://www.ecma-international.org/ecma-262/6.0/#sec-setintegritylevel
  753. SetIntegrityLevel: function SetIntegrityLevel(O, level) {
  754. if (this.Type(O) !== 'Object') {
  755. throw new $TypeError('Assertion failed: Type(O) is not Object');
  756. }
  757. if (level !== 'sealed' && level !== 'frozen') {
  758. throw new $TypeError('Assertion failed: `level` must be `"sealed"` or `"frozen"`');
  759. }
  760. if (!$preventExtensions) {
  761. throw new $SyntaxError('SetIntegrityLevel requires native `Object.preventExtensions` support');
  762. }
  763. var status = $preventExtensions(O);
  764. if (!status) {
  765. return false;
  766. }
  767. if (!$gOPN) {
  768. throw new $SyntaxError('SetIntegrityLevel requires native `Object.getOwnPropertyNames` support');
  769. }
  770. var theKeys = $gOPN(O);
  771. var ES = this;
  772. if (level === 'sealed') {
  773. forEach(theKeys, function (k) {
  774. ES.DefinePropertyOrThrow(O, k, { configurable: false });
  775. });
  776. } else if (level === 'frozen') {
  777. forEach(theKeys, function (k) {
  778. var currentDesc = $gOPD(O, k);
  779. if (typeof currentDesc !== 'undefined') {
  780. var desc;
  781. if (ES.IsAccessorDescriptor(ES.ToPropertyDescriptor(currentDesc))) {
  782. desc = { configurable: false };
  783. } else {
  784. desc = { configurable: false, writable: false };
  785. }
  786. ES.DefinePropertyOrThrow(O, k, desc);
  787. }
  788. });
  789. }
  790. return true;
  791. },
  792. // https://www.ecma-international.org/ecma-262/6.0/#sec-testintegritylevel
  793. TestIntegrityLevel: function TestIntegrityLevel(O, level) {
  794. if (this.Type(O) !== 'Object') {
  795. throw new $TypeError('Assertion failed: Type(O) is not Object');
  796. }
  797. if (level !== 'sealed' && level !== 'frozen') {
  798. throw new $TypeError('Assertion failed: `level` must be `"sealed"` or `"frozen"`');
  799. }
  800. var status = this.IsExtensible(O);
  801. if (status) {
  802. return false;
  803. }
  804. var theKeys = $gOPN(O);
  805. var ES = this;
  806. return theKeys.length === 0 || every(theKeys, function (k) {
  807. var currentDesc = $gOPD(O, k);
  808. if (typeof currentDesc !== 'undefined') {
  809. if (currentDesc.configurable) {
  810. return false;
  811. }
  812. if (level === 'frozen' && ES.IsDataDescriptor(ES.ToPropertyDescriptor(currentDesc)) && currentDesc.writable) {
  813. return false;
  814. }
  815. }
  816. return true;
  817. });
  818. },
  819. // https://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance
  820. OrdinaryHasInstance: function OrdinaryHasInstance(C, O) {
  821. if (this.IsCallable(C) === false) {
  822. return false;
  823. }
  824. if (this.Type(O) !== 'Object') {
  825. return false;
  826. }
  827. var P = this.Get(C, 'prototype');
  828. if (this.Type(P) !== 'Object') {
  829. throw new $TypeError('OrdinaryHasInstance called on an object with an invalid prototype property.');
  830. }
  831. return O instanceof C;
  832. },
  833. // https://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasproperty
  834. OrdinaryHasProperty: function OrdinaryHasProperty(O, P) {
  835. if (this.Type(O) !== 'Object') {
  836. throw new $TypeError('Assertion failed: Type(O) is not Object');
  837. }
  838. if (!this.IsPropertyKey(P)) {
  839. throw new $TypeError('Assertion failed: P must be a Property Key');
  840. }
  841. return P in O;
  842. },
  843. // https://www.ecma-international.org/ecma-262/6.0/#sec-instanceofoperator
  844. InstanceofOperator: function InstanceofOperator(O, C) {
  845. if (this.Type(O) !== 'Object') {
  846. throw new $TypeError('Assertion failed: Type(O) is not Object');
  847. }
  848. var instOfHandler = hasSymbols && $Symbol.hasInstance ? this.GetMethod(C, $Symbol.hasInstance) : void 0;
  849. if (typeof instOfHandler !== 'undefined') {
  850. return this.ToBoolean(this.Call(instOfHandler, C, [O]));
  851. }
  852. if (!this.IsCallable(C)) {
  853. throw new $TypeError('`C` is not Callable');
  854. }
  855. return this.OrdinaryHasInstance(C, O);
  856. },
  857. // https://www.ecma-international.org/ecma-262/6.0/#sec-ispromise
  858. IsPromise: function IsPromise(x) {
  859. if (this.Type(x) !== 'Object') {
  860. return false;
  861. }
  862. if (!$PromiseThen) { // Promises are not supported
  863. return false;
  864. }
  865. try {
  866. $PromiseThen(x); // throws if not a promise
  867. } catch (e) {
  868. return false;
  869. }
  870. return true;
  871. },
  872. // https://www.ecma-international.org/ecma-262/6.0/#sec-abstract-equality-comparison
  873. 'Abstract Equality Comparison': function AbstractEqualityComparison(x, y) {
  874. var xType = this.Type(x);
  875. var yType = this.Type(y);
  876. if (xType === yType) {
  877. return x === y; // ES6+ specified this shortcut anyways.
  878. }
  879. if (x == null && y == null) {
  880. return true;
  881. }
  882. if (xType === 'Number' && yType === 'String') {
  883. return this['Abstract Equality Comparison'](x, this.ToNumber(y));
  884. }
  885. if (xType === 'String' && yType === 'Number') {
  886. return this['Abstract Equality Comparison'](this.ToNumber(x), y);
  887. }
  888. if (xType === 'Boolean') {
  889. return this['Abstract Equality Comparison'](this.ToNumber(x), y);
  890. }
  891. if (yType === 'Boolean') {
  892. return this['Abstract Equality Comparison'](x, this.ToNumber(y));
  893. }
  894. if ((xType === 'String' || xType === 'Number' || xType === 'Symbol') && yType === 'Object') {
  895. return this['Abstract Equality Comparison'](x, this.ToPrimitive(y));
  896. }
  897. if (xType === 'Object' && (yType === 'String' || yType === 'Number' || yType === 'Symbol')) {
  898. return this['Abstract Equality Comparison'](this.ToPrimitive(x), y);
  899. }
  900. return false;
  901. },
  902. // eslint-disable-next-line max-lines-per-function, max-statements, id-length, max-params
  903. ValidateAndApplyPropertyDescriptor: function ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current) {
  904. // this uses the ES2017+ logic, since it fixes a number of bugs in the ES2015 logic.
  905. var oType = this.Type(O);
  906. if (oType !== 'Undefined' && oType !== 'Object') {
  907. throw new $TypeError('Assertion failed: O must be undefined or an Object');
  908. }
  909. if (this.Type(extensible) !== 'Boolean') {
  910. throw new $TypeError('Assertion failed: extensible must be a Boolean');
  911. }
  912. if (!isPropertyDescriptor(this, Desc)) {
  913. throw new $TypeError('Assertion failed: Desc must be a Property Descriptor');
  914. }
  915. if (this.Type(current) !== 'Undefined' && !isPropertyDescriptor(this, current)) {
  916. throw new $TypeError('Assertion failed: current must be a Property Descriptor, or undefined');
  917. }
  918. if (oType !== 'Undefined' && !this.IsPropertyKey(P)) {
  919. throw new $TypeError('Assertion failed: if O is not undefined, P must be a Property Key');
  920. }
  921. if (this.Type(current) === 'Undefined') {
  922. if (!extensible) {
  923. return false;
  924. }
  925. if (this.IsGenericDescriptor(Desc) || this.IsDataDescriptor(Desc)) {
  926. if (oType !== 'Undefined') {
  927. DefineOwnProperty(this, O, P, {
  928. '[[Configurable]]': Desc['[[Configurable]]'],
  929. '[[Enumerable]]': Desc['[[Enumerable]]'],
  930. '[[Value]]': Desc['[[Value]]'],
  931. '[[Writable]]': Desc['[[Writable]]']
  932. });
  933. }
  934. } else {
  935. if (!this.IsAccessorDescriptor(Desc)) {
  936. throw new $TypeError('Assertion failed: Desc is not an accessor descriptor');
  937. }
  938. if (oType !== 'Undefined') {
  939. return DefineOwnProperty(this, O, P, Desc);
  940. }
  941. }
  942. return true;
  943. }
  944. if (this.IsGenericDescriptor(Desc) && !('[[Configurable]]' in Desc) && !('[[Enumerable]]' in Desc)) {
  945. return true;
  946. }
  947. if (isSamePropertyDescriptor(this, Desc, current)) {
  948. return true; // removed by ES2017, but should still be correct
  949. }
  950. // "if every field in Desc is absent, return true" can't really match the assertion that it's a Property Descriptor
  951. if (!current['[[Configurable]]']) {
  952. if (Desc['[[Configurable]]']) {
  953. return false;
  954. }
  955. if ('[[Enumerable]]' in Desc && !Desc['[[Enumerable]]'] === !!current['[[Enumerable]]']) {
  956. return false;
  957. }
  958. }
  959. if (this.IsGenericDescriptor(Desc)) {
  960. // no further validation is required.
  961. } else if (this.IsDataDescriptor(current) !== this.IsDataDescriptor(Desc)) {
  962. if (!current['[[Configurable]]']) {
  963. return false;
  964. }
  965. if (this.IsDataDescriptor(current)) {
  966. if (oType !== 'Undefined') {
  967. DefineOwnProperty(this, O, P, {
  968. '[[Configurable]]': current['[[Configurable]]'],
  969. '[[Enumerable]]': current['[[Enumerable]]'],
  970. '[[Get]]': undefined
  971. });
  972. }
  973. } else if (oType !== 'Undefined') {
  974. DefineOwnProperty(this, O, P, {
  975. '[[Configurable]]': current['[[Configurable]]'],
  976. '[[Enumerable]]': current['[[Enumerable]]'],
  977. '[[Value]]': undefined
  978. });
  979. }
  980. } else if (this.IsDataDescriptor(current) && this.IsDataDescriptor(Desc)) {
  981. if (!current['[[Configurable]]'] && !current['[[Writable]]']) {
  982. if ('[[Writable]]' in Desc && Desc['[[Writable]]']) {
  983. return false;
  984. }
  985. if ('[[Value]]' in Desc && !this.SameValue(Desc['[[Value]]'], current['[[Value]]'])) {
  986. return false;
  987. }
  988. return true;
  989. }
  990. } else if (this.IsAccessorDescriptor(current) && this.IsAccessorDescriptor(Desc)) {
  991. if (!current['[[Configurable]]']) {
  992. if ('[[Set]]' in Desc && !this.SameValue(Desc['[[Set]]'], current['[[Set]]'])) {
  993. return false;
  994. }
  995. if ('[[Get]]' in Desc && !this.SameValue(Desc['[[Get]]'], current['[[Get]]'])) {
  996. return false;
  997. }
  998. return true;
  999. }
  1000. } else {
  1001. throw new $TypeError('Assertion failed: current and Desc are not both data, both accessors, or one accessor and one data.');
  1002. }
  1003. if (oType !== 'Undefined') {
  1004. return DefineOwnProperty(this, O, P, Desc);
  1005. }
  1006. return true;
  1007. },
  1008. // https://www.ecma-international.org/ecma-262/6.0/#sec-ordinarydefineownproperty
  1009. OrdinaryDefineOwnProperty: function OrdinaryDefineOwnProperty(O, P, Desc) {
  1010. if (this.Type(O) !== 'Object') {
  1011. throw new $TypeError('Assertion failed: O must be an Object');
  1012. }
  1013. if (!this.IsPropertyKey(P)) {
  1014. throw new $TypeError('Assertion failed: P must be a Property Key');
  1015. }
  1016. if (!isPropertyDescriptor(this, Desc)) {
  1017. throw new $TypeError('Assertion failed: Desc must be a Property Descriptor');
  1018. }
  1019. var desc = $gOPD(O, P);
  1020. var current = desc && this.ToPropertyDescriptor(desc);
  1021. var extensible = this.IsExtensible(O);
  1022. return this.ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current);
  1023. },
  1024. // https://www.ecma-international.org/ecma-262/6.0/#sec-ordinarygetownproperty
  1025. OrdinaryGetOwnProperty: function OrdinaryGetOwnProperty(O, P) {
  1026. if (this.Type(O) !== 'Object') {
  1027. throw new $TypeError('Assertion failed: O must be an Object');
  1028. }
  1029. if (!this.IsPropertyKey(P)) {
  1030. throw new $TypeError('Assertion failed: P must be a Property Key');
  1031. }
  1032. if (!has(O, P)) {
  1033. return void 0;
  1034. }
  1035. if (!$gOPD) {
  1036. // ES3 fallback
  1037. var arrayLength = this.IsArray(O) && P === 'length';
  1038. var regexLastIndex = this.IsRegExp(O) && P === 'lastIndex';
  1039. return {
  1040. '[[Configurable]]': !(arrayLength || regexLastIndex),
  1041. '[[Enumerable]]': $isEnumerable(O, P),
  1042. '[[Value]]': O[P],
  1043. '[[Writable]]': true
  1044. };
  1045. }
  1046. return this.ToPropertyDescriptor($gOPD(O, P));
  1047. },
  1048. // https://www.ecma-international.org/ecma-262/6.0/#sec-arraycreate
  1049. ArrayCreate: function ArrayCreate(length) {
  1050. if (!this.IsInteger(length) || length < 0) {
  1051. throw new $TypeError('Assertion failed: `length` must be an integer Number >= 0');
  1052. }
  1053. if (length > MAX_ARRAY_LENGTH) {
  1054. throw new $RangeError('length is greater than (2**32 - 1)');
  1055. }
  1056. var proto = arguments.length > 1 ? arguments[1] : $ArrayPrototype;
  1057. var A = []; // steps 5 - 7, and 9
  1058. if (proto !== $ArrayPrototype) { // step 8
  1059. if (!$setProto) {
  1060. throw new $SyntaxError('ArrayCreate: a `proto` argument that is not `Array.prototype` is not supported in an environment that does not support setting the [[Prototype]]');
  1061. }
  1062. $setProto(A, proto);
  1063. }
  1064. if (length !== 0) { // bypasses the need for step 2
  1065. A.length = length;
  1066. }
  1067. /* step 10, the above as a shortcut for the below
  1068. this.OrdinaryDefineOwnProperty(A, 'length', {
  1069. '[[Configurable]]': false,
  1070. '[[Enumerable]]': false,
  1071. '[[Value]]': length,
  1072. '[[Writable]]': true
  1073. });
  1074. */
  1075. return A;
  1076. },
  1077. // eslint-disable-next-line max-statements, max-lines-per-function
  1078. ArraySetLength: function ArraySetLength(A, Desc) {
  1079. if (!this.IsArray(A)) {
  1080. throw new $TypeError('Assertion failed: A must be an Array');
  1081. }
  1082. if (!isPropertyDescriptor(this, Desc)) {
  1083. throw new $TypeError('Assertion failed: Desc must be a Property Descriptor');
  1084. }
  1085. if (!('[[Value]]' in Desc)) {
  1086. return this.OrdinaryDefineOwnProperty(A, 'length', Desc);
  1087. }
  1088. var newLenDesc = assign({}, Desc);
  1089. var newLen = this.ToUint32(Desc['[[Value]]']);
  1090. var numberLen = this.ToNumber(Desc['[[Value]]']);
  1091. if (newLen !== numberLen) {
  1092. throw new $RangeError('Invalid array length');
  1093. }
  1094. newLenDesc['[[Value]]'] = newLen;
  1095. var oldLenDesc = this.OrdinaryGetOwnProperty(A, 'length');
  1096. if (!this.IsDataDescriptor(oldLenDesc)) {
  1097. throw new $TypeError('Assertion failed: an array had a non-data descriptor on `length`');
  1098. }
  1099. var oldLen = oldLenDesc['[[Value]]'];
  1100. if (newLen >= oldLen) {
  1101. return this.OrdinaryDefineOwnProperty(A, 'length', newLenDesc);
  1102. }
  1103. if (!oldLenDesc['[[Writable]]']) {
  1104. return false;
  1105. }
  1106. var newWritable;
  1107. if (!('[[Writable]]' in newLenDesc) || newLenDesc['[[Writable]]']) {
  1108. newWritable = true;
  1109. } else {
  1110. newWritable = false;
  1111. newLenDesc['[[Writable]]'] = true;
  1112. }
  1113. var succeeded = this.OrdinaryDefineOwnProperty(A, 'length', newLenDesc);
  1114. if (!succeeded) {
  1115. return false;
  1116. }
  1117. while (newLen < oldLen) {
  1118. oldLen -= 1;
  1119. var deleteSucceeded = delete A[this.ToString(oldLen)];
  1120. if (!deleteSucceeded) {
  1121. newLenDesc['[[Value]]'] = oldLen + 1;
  1122. if (!newWritable) {
  1123. newLenDesc['[[Writable]]'] = false;
  1124. this.OrdinaryDefineOwnProperty(A, 'length', newLenDesc);
  1125. return false;
  1126. }
  1127. }
  1128. }
  1129. if (!newWritable) {
  1130. return this.OrdinaryDefineOwnProperty(A, 'length', { '[[Writable]]': false });
  1131. }
  1132. return true;
  1133. },
  1134. // https://www.ecma-international.org/ecma-262/6.0/#sec-createhtml
  1135. CreateHTML: function CreateHTML(string, tag, attribute, value) {
  1136. if (this.Type(tag) !== 'String' || this.Type(attribute) !== 'String') {
  1137. throw new $TypeError('Assertion failed: `tag` and `attribute` must be strings');
  1138. }
  1139. var str = this.RequireObjectCoercible(string);
  1140. var S = this.ToString(str);
  1141. var p1 = '<' + tag;
  1142. if (attribute !== '') {
  1143. var V = this.ToString(value);
  1144. var escapedV = $replace(V, /\x22/g, '&quot;');
  1145. p1 += '\x20' + attribute + '\x3D\x22' + escapedV + '\x22';
  1146. }
  1147. return p1 + '>' + S + '</' + tag + '>';
  1148. },
  1149. // https://www.ecma-international.org/ecma-262/6.0/#sec-getownpropertykeys
  1150. GetOwnPropertyKeys: function GetOwnPropertyKeys(O, Type) {
  1151. if (this.Type(O) !== 'Object') {
  1152. throw new $TypeError('Assertion failed: Type(O) is not Object');
  1153. }
  1154. if (Type === 'Symbol') {
  1155. return hasSymbols && $gOPS ? $gOPS(O) : [];
  1156. }
  1157. if (Type === 'String') {
  1158. if (!$gOPN) {
  1159. return keys(O);
  1160. }
  1161. return $gOPN(O);
  1162. }
  1163. throw new $TypeError('Assertion failed: `Type` must be `"String"` or `"Symbol"`');
  1164. },
  1165. // https://www.ecma-international.org/ecma-262/6.0/#sec-symboldescriptivestring
  1166. SymbolDescriptiveString: function SymbolDescriptiveString(sym) {
  1167. if (this.Type(sym) !== 'Symbol') {
  1168. throw new $TypeError('Assertion failed: `sym` must be a Symbol');
  1169. }
  1170. return $SymbolToString(sym);
  1171. },
  1172. // https://www.ecma-international.org/ecma-262/6.0/#sec-getsubstitution
  1173. // eslint-disable-next-line max-statements, max-params, max-lines-per-function
  1174. GetSubstitution: function GetSubstitution(matched, str, position, captures, replacement) {
  1175. if (this.Type(matched) !== 'String') {
  1176. throw new $TypeError('Assertion failed: `matched` must be a String');
  1177. }
  1178. var matchLength = matched.length;
  1179. if (this.Type(str) !== 'String') {
  1180. throw new $TypeError('Assertion failed: `str` must be a String');
  1181. }
  1182. var stringLength = str.length;
  1183. if (!this.IsInteger(position) || position < 0 || position > stringLength) {
  1184. throw new $TypeError('Assertion failed: `position` must be a nonnegative integer, and less than or equal to the length of `string`, got ' + inspect(position));
  1185. }
  1186. var ES = this;
  1187. var isStringOrHole = function (capture, index, arr) { return ES.Type(capture) === 'String' || !(index in arr); };
  1188. if (!this.IsArray(captures) || !every(captures, isStringOrHole)) {
  1189. throw new $TypeError('Assertion failed: `captures` must be a List of Strings, got ' + inspect(captures));
  1190. }
  1191. if (this.Type(replacement) !== 'String') {
  1192. throw new $TypeError('Assertion failed: `replacement` must be a String');
  1193. }
  1194. var tailPos = position + matchLength;
  1195. var m = captures.length;
  1196. var result = '';
  1197. for (var i = 0; i < replacement.length; i += 1) {
  1198. // if this is a $, and it's not the end of the replacement
  1199. var current = replacement[i];
  1200. var isLast = (i + 1) >= replacement.length;
  1201. var nextIsLast = (i + 2) >= replacement.length;
  1202. if (current === '$' && !isLast) {
  1203. var next = replacement[i + 1];
  1204. if (next === '$') {
  1205. result += '$';
  1206. i += 1;
  1207. } else if (next === '&') {
  1208. result += matched;
  1209. i += 1;
  1210. } else if (next === '`') {
  1211. result += position === 0 ? '' : strSlice(str, 0, position - 1);
  1212. i += 1;
  1213. } else if (next === "'") {
  1214. result += tailPos >= stringLength ? '' : strSlice(str, tailPos);
  1215. i += 1;
  1216. } else {
  1217. var nextNext = nextIsLast ? null : replacement[i + 2];
  1218. if (isDigit(next) && next !== '0' && (nextIsLast || !isDigit(nextNext))) {
  1219. // $1 through $9, and not followed by a digit
  1220. var n = parseInteger(next, 10);
  1221. // if (n > m, impl-defined)
  1222. result += (n <= m && this.Type(captures[n - 1]) === 'Undefined') ? '' : captures[n - 1];
  1223. i += 1;
  1224. } else if (isDigit(next) && (nextIsLast || isDigit(nextNext))) {
  1225. // $00 through $99
  1226. var nn = next + nextNext;
  1227. var nnI = parseInteger(nn, 10) - 1;
  1228. // if nn === '00' or nn > m, impl-defined
  1229. result += (nn <= m && this.Type(captures[nnI]) === 'Undefined') ? '' : captures[nnI];
  1230. i += 2;
  1231. } else {
  1232. result += '$';
  1233. }
  1234. }
  1235. } else {
  1236. // the final $, or else not a $
  1237. result += replacement[i];
  1238. }
  1239. }
  1240. return result;
  1241. },
  1242. // https://ecma-international.org/ecma-262/6.0/#sec-todatestring
  1243. ToDateString: function ToDateString(tv) {
  1244. if (this.Type(tv) !== 'Number') {
  1245. throw new $TypeError('Assertion failed: `tv` must be a Number');
  1246. }
  1247. if ($isNaN(tv)) {
  1248. return 'Invalid Date';
  1249. }
  1250. return $Date(tv);
  1251. },
  1252. // https://ecma-international.org/ecma-262/6.0/#sec-createlistfromarraylike
  1253. CreateListFromArrayLike: function CreateListFromArrayLike(obj) {
  1254. var elementTypes = arguments.length > 1
  1255. ? arguments[1]
  1256. : ['Undefined', 'Null', 'Boolean', 'String', 'Symbol', 'Number', 'Object'];
  1257. if (this.Type(obj) !== 'Object') {
  1258. throw new $TypeError('Assertion failed: `obj` must be an Object');
  1259. }
  1260. if (!this.IsArray(elementTypes)) {
  1261. throw new $TypeError('Assertion failed: `elementTypes`, if provided, must be an array');
  1262. }
  1263. var len = this.ToLength(this.Get(obj, 'length'));
  1264. var list = [];
  1265. var index = 0;
  1266. while (index < len) {
  1267. var indexName = this.ToString(index);
  1268. var next = this.Get(obj, indexName);
  1269. var nextType = this.Type(next);
  1270. if ($indexOf(elementTypes, nextType) < 0) {
  1271. throw new $TypeError('item type ' + nextType + ' is not a valid elementType');
  1272. }
  1273. $push(list, next);
  1274. index += 1;
  1275. }
  1276. return list;
  1277. },
  1278. // https://ecma-international.org/ecma-262/6.0/#sec-getprototypefromconstructor
  1279. GetPrototypeFromConstructor: function GetPrototypeFromConstructor(constructor, intrinsicDefaultProto) {
  1280. var intrinsic = GetIntrinsic(intrinsicDefaultProto); // throws if not a valid intrinsic
  1281. if (!this.IsConstructor(constructor)) {
  1282. throw new $TypeError('Assertion failed: `constructor` must be a constructor');
  1283. }
  1284. var proto = this.Get(constructor, 'prototype');
  1285. if (this.Type(proto) !== 'Object') {
  1286. if (!(constructor instanceof $Function)) {
  1287. // ignore other realms, for now
  1288. throw new $TypeError('cross-realm constructors not currently supported');
  1289. }
  1290. proto = intrinsic;
  1291. }
  1292. return proto;
  1293. },
  1294. // https://ecma-international.org/ecma-262/6.0/#sec-setfunctionname
  1295. SetFunctionName: function SetFunctionName(F, name) {
  1296. if (typeof F !== 'function') {
  1297. throw new $TypeError('Assertion failed: `F` must be a function');
  1298. }
  1299. if (!this.IsExtensible(F) || has(F, 'name')) {
  1300. throw new $TypeError('Assertion failed: `F` must be extensible, and must not have a `name` own property');
  1301. }
  1302. var nameType = this.Type(name);
  1303. if (nameType !== 'Symbol' && nameType !== 'String') {
  1304. throw new $TypeError('Assertion failed: `name` must be a Symbol or a String');
  1305. }
  1306. if (nameType === 'Symbol') {
  1307. var description = getSymbolDescription(name);
  1308. // eslint-disable-next-line no-param-reassign
  1309. name = typeof description === 'undefined' ? '' : '[' + description + ']';
  1310. }
  1311. if (arguments.length > 2) {
  1312. var prefix = arguments[2];
  1313. // eslint-disable-next-line no-param-reassign
  1314. name = prefix + ' ' + name;
  1315. }
  1316. return this.DefinePropertyOrThrow(F, 'name', {
  1317. '[[Value]]': name,
  1318. '[[Writable]]': false,
  1319. '[[Enumerable]]': false,
  1320. '[[Configurable]]': true
  1321. });
  1322. }
  1323. });
  1324. delete ES6.CheckObjectCoercible; // renamed in ES6 to RequireObjectCoercible
  1325. module.exports = ES6;