• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3var has = require('has');
4var toPrimitive = require('es-to-primitive/es6');
5
6var GetIntrinsic = require('./GetIntrinsic');
7
8var $TypeError = GetIntrinsic('%TypeError%');
9var $SyntaxError = GetIntrinsic('%SyntaxError%');
10var $Array = GetIntrinsic('%Array%');
11var $String = GetIntrinsic('%String%');
12var $Object = GetIntrinsic('%Object%');
13var $Number = GetIntrinsic('%Number%');
14var $Symbol = GetIntrinsic('%Symbol%', true);
15var $RegExp = GetIntrinsic('%RegExp%');
16
17var hasSymbols = !!$Symbol;
18
19var $isNaN = require('./helpers/isNaN');
20var $isFinite = require('./helpers/isFinite');
21var MAX_SAFE_INTEGER = $Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1;
22
23var assign = require('./helpers/assign');
24var sign = require('./helpers/sign');
25var mod = require('./helpers/mod');
26var isPrimitive = require('./helpers/isPrimitive');
27var parseInteger = parseInt;
28var bind = require('function-bind');
29var arraySlice = bind.call(Function.call, $Array.prototype.slice);
30var strSlice = bind.call(Function.call, $String.prototype.slice);
31var isBinary = bind.call(Function.call, $RegExp.prototype.test, /^0b[01]+$/i);
32var isOctal = bind.call(Function.call, $RegExp.prototype.test, /^0o[0-7]+$/i);
33var regexExec = bind.call(Function.call, $RegExp.prototype.exec);
34var nonWS = ['\u0085', '\u200b', '\ufffe'].join('');
35var nonWSregex = new $RegExp('[' + nonWS + ']', 'g');
36var hasNonWS = bind.call(Function.call, $RegExp.prototype.test, nonWSregex);
37var invalidHexLiteral = /^[-+]0x[0-9a-f]+$/i;
38var isInvalidHexLiteral = bind.call(Function.call, $RegExp.prototype.test, invalidHexLiteral);
39var $charCodeAt = bind.call(Function.call, $String.prototype.charCodeAt);
40
41var toStr = bind.call(Function.call, Object.prototype.toString);
42
43var $floor = Math.floor;
44var $abs = Math.abs;
45
46var $ObjectCreate = Object.create;
47var $gOPD = $Object.getOwnPropertyDescriptor;
48
49var $isExtensible = $Object.isExtensible;
50
51// whitespace from: http://es5.github.io/#x15.5.4.20
52// implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
53var ws = [
54	'\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003',
55	'\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028',
56	'\u2029\uFEFF'
57].join('');
58var trimRegex = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');
59var replace = bind.call(Function.call, $String.prototype.replace);
60var trim = function (value) {
61	return replace(value, trimRegex, '');
62};
63
64var ES5 = require('./es5');
65
66var hasRegExpMatcher = require('is-regex');
67
68// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-abstract-operations
69var ES6 = assign(assign({}, ES5), {
70
71	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-call-f-v-args
72	Call: function Call(F, V) {
73		var args = arguments.length > 2 ? arguments[2] : [];
74		if (!this.IsCallable(F)) {
75			throw new $TypeError(F + ' is not a function');
76		}
77		return F.apply(V, args);
78	},
79
80	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toprimitive
81	ToPrimitive: toPrimitive,
82
83	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toboolean
84	// ToBoolean: ES5.ToBoolean,
85
86	// https://ecma-international.org/ecma-262/6.0/#sec-tonumber
87	ToNumber: function ToNumber(argument) {
88		var value = isPrimitive(argument) ? argument : toPrimitive(argument, $Number);
89		if (typeof value === 'symbol') {
90			throw new $TypeError('Cannot convert a Symbol value to a number');
91		}
92		if (typeof value === 'string') {
93			if (isBinary(value)) {
94				return this.ToNumber(parseInteger(strSlice(value, 2), 2));
95			} else if (isOctal(value)) {
96				return this.ToNumber(parseInteger(strSlice(value, 2), 8));
97			} else if (hasNonWS(value) || isInvalidHexLiteral(value)) {
98				return NaN;
99			} else {
100				var trimmed = trim(value);
101				if (trimmed !== value) {
102					return this.ToNumber(trimmed);
103				}
104			}
105		}
106		return $Number(value);
107	},
108
109	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tointeger
110	// ToInteger: ES5.ToNumber,
111
112	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint32
113	// ToInt32: ES5.ToInt32,
114
115	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint32
116	// ToUint32: ES5.ToUint32,
117
118	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint16
119	ToInt16: function ToInt16(argument) {
120		var int16bit = this.ToUint16(argument);
121		return int16bit >= 0x8000 ? int16bit - 0x10000 : int16bit;
122	},
123
124	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint16
125	// ToUint16: ES5.ToUint16,
126
127	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toint8
128	ToInt8: function ToInt8(argument) {
129		var int8bit = this.ToUint8(argument);
130		return int8bit >= 0x80 ? int8bit - 0x100 : int8bit;
131	},
132
133	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint8
134	ToUint8: function ToUint8(argument) {
135		var number = this.ToNumber(argument);
136		if ($isNaN(number) || number === 0 || !$isFinite(number)) { return 0; }
137		var posInt = sign(number) * $floor($abs(number));
138		return mod(posInt, 0x100);
139	},
140
141	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-touint8clamp
142	ToUint8Clamp: function ToUint8Clamp(argument) {
143		var number = this.ToNumber(argument);
144		if ($isNaN(number) || number <= 0) { return 0; }
145		if (number >= 0xFF) { return 0xFF; }
146		var f = $floor(argument);
147		if (f + 0.5 < number) { return f + 1; }
148		if (number < f + 0.5) { return f; }
149		if (f % 2 !== 0) { return f + 1; }
150		return f;
151	},
152
153	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tostring
154	ToString: function ToString(argument) {
155		if (typeof argument === 'symbol') {
156			throw new $TypeError('Cannot convert a Symbol value to a string');
157		}
158		return $String(argument);
159	},
160
161	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-toobject
162	ToObject: function ToObject(value) {
163		this.RequireObjectCoercible(value);
164		return $Object(value);
165	},
166
167	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-topropertykey
168	ToPropertyKey: function ToPropertyKey(argument) {
169		var key = this.ToPrimitive(argument, $String);
170		return typeof key === 'symbol' ? key : this.ToString(key);
171	},
172
173	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
174	ToLength: function ToLength(argument) {
175		var len = this.ToInteger(argument);
176		if (len <= 0) { return 0; } // includes converting -0 to +0
177		if (len > MAX_SAFE_INTEGER) { return MAX_SAFE_INTEGER; }
178		return len;
179	},
180
181	// https://ecma-international.org/ecma-262/6.0/#sec-canonicalnumericindexstring
182	CanonicalNumericIndexString: function CanonicalNumericIndexString(argument) {
183		if (toStr(argument) !== '[object String]') {
184			throw new $TypeError('must be a string');
185		}
186		if (argument === '-0') { return -0; }
187		var n = this.ToNumber(argument);
188		if (this.SameValue(this.ToString(n), argument)) { return n; }
189		return void 0;
190	},
191
192	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-requireobjectcoercible
193	RequireObjectCoercible: ES5.CheckObjectCoercible,
194
195	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isarray
196	IsArray: $Array.isArray || function IsArray(argument) {
197		return toStr(argument) === '[object Array]';
198	},
199
200	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-iscallable
201	// IsCallable: ES5.IsCallable,
202
203	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isconstructor
204	IsConstructor: function IsConstructor(argument) {
205		return typeof argument === 'function' && !!argument.prototype; // unfortunately there's no way to truly check this without try/catch `new argument`
206	},
207
208	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isextensible-o
209	IsExtensible: Object.preventExtensions
210		? function IsExtensible(obj) {
211			if (isPrimitive(obj)) {
212				return false;
213			}
214			return $isExtensible(obj);
215		}
216		: function isExtensible(obj) { return true; }, // eslint-disable-line no-unused-vars
217
218	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-isinteger
219	IsInteger: function IsInteger(argument) {
220		if (typeof argument !== 'number' || $isNaN(argument) || !$isFinite(argument)) {
221			return false;
222		}
223		var abs = $abs(argument);
224		return $floor(abs) === abs;
225	},
226
227	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ispropertykey
228	IsPropertyKey: function IsPropertyKey(argument) {
229		return typeof argument === 'string' || typeof argument === 'symbol';
230	},
231
232	// https://ecma-international.org/ecma-262/6.0/#sec-isregexp
233	IsRegExp: function IsRegExp(argument) {
234		if (!argument || typeof argument !== 'object') {
235			return false;
236		}
237		if (hasSymbols) {
238			var isRegExp = argument[$Symbol.match];
239			if (typeof isRegExp !== 'undefined') {
240				return ES5.ToBoolean(isRegExp);
241			}
242		}
243		return hasRegExpMatcher(argument);
244	},
245
246	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue
247	// SameValue: ES5.SameValue,
248
249	// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero
250	SameValueZero: function SameValueZero(x, y) {
251		return (x === y) || ($isNaN(x) && $isNaN(y));
252	},
253
254	/**
255	 * 7.3.2 GetV (V, P)
256	 * 1. Assert: IsPropertyKey(P) is true.
257	 * 2. Let O be ToObject(V).
258	 * 3. ReturnIfAbrupt(O).
259	 * 4. Return O.[[Get]](P, V).
260	 */
261	GetV: function GetV(V, P) {
262		// 7.3.2.1
263		if (!this.IsPropertyKey(P)) {
264			throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
265		}
266
267		// 7.3.2.2-3
268		var O = this.ToObject(V);
269
270		// 7.3.2.4
271		return O[P];
272	},
273
274	/**
275	 * 7.3.9 - https://ecma-international.org/ecma-262/6.0/#sec-getmethod
276	 * 1. Assert: IsPropertyKey(P) is true.
277	 * 2. Let func be GetV(O, P).
278	 * 3. ReturnIfAbrupt(func).
279	 * 4. If func is either undefined or null, return undefined.
280	 * 5. If IsCallable(func) is false, throw a TypeError exception.
281	 * 6. Return func.
282	 */
283	GetMethod: function GetMethod(O, P) {
284		// 7.3.9.1
285		if (!this.IsPropertyKey(P)) {
286			throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
287		}
288
289		// 7.3.9.2
290		var func = this.GetV(O, P);
291
292		// 7.3.9.4
293		if (func == null) {
294			return void 0;
295		}
296
297		// 7.3.9.5
298		if (!this.IsCallable(func)) {
299			throw new $TypeError(P + 'is not a function');
300		}
301
302		// 7.3.9.6
303		return func;
304	},
305
306	/**
307	 * 7.3.1 Get (O, P) - https://ecma-international.org/ecma-262/6.0/#sec-get-o-p
308	 * 1. Assert: Type(O) is Object.
309	 * 2. Assert: IsPropertyKey(P) is true.
310	 * 3. Return O.[[Get]](P, O).
311	 */
312	Get: function Get(O, P) {
313		// 7.3.1.1
314		if (this.Type(O) !== 'Object') {
315			throw new $TypeError('Assertion failed: Type(O) is not Object');
316		}
317		// 7.3.1.2
318		if (!this.IsPropertyKey(P)) {
319			throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
320		}
321		// 7.3.1.3
322		return O[P];
323	},
324
325	Type: function Type(x) {
326		if (typeof x === 'symbol') {
327			return 'Symbol';
328		}
329		return ES5.Type(x);
330	},
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
354	// https://ecma-international.org/ecma-262/6.0/#sec-completepropertydescriptor
355	CompletePropertyDescriptor: function CompletePropertyDescriptor(Desc) {
356		if (!this.IsPropertyDescriptor(Desc)) {
357			throw new $TypeError('Desc must be a Property Descriptor');
358		}
359
360		if (this.IsGenericDescriptor(Desc) || this.IsDataDescriptor(Desc)) {
361			if (!has(Desc, '[[Value]]')) {
362				Desc['[[Value]]'] = void 0;
363			}
364			if (!has(Desc, '[[Writable]]')) {
365				Desc['[[Writable]]'] = false;
366			}
367		} else {
368			if (!has(Desc, '[[Get]]')) {
369				Desc['[[Get]]'] = void 0;
370			}
371			if (!has(Desc, '[[Set]]')) {
372				Desc['[[Set]]'] = void 0;
373			}
374		}
375		if (!has(Desc, '[[Enumerable]]')) {
376			Desc['[[Enumerable]]'] = false;
377		}
378		if (!has(Desc, '[[Configurable]]')) {
379			Desc['[[Configurable]]'] = false;
380		}
381		return Desc;
382	},
383
384	// https://ecma-international.org/ecma-262/6.0/#sec-set-o-p-v-throw
385	Set: function Set(O, P, V, Throw) {
386		if (this.Type(O) !== 'Object') {
387			throw new $TypeError('O must be an Object');
388		}
389		if (!this.IsPropertyKey(P)) {
390			throw new $TypeError('P must be a Property Key');
391		}
392		if (this.Type(Throw) !== 'Boolean') {
393			throw new $TypeError('Throw must be a Boolean');
394		}
395		if (Throw) {
396			O[P] = V;
397			return true;
398		} else {
399			try {
400				O[P] = V;
401			} catch (e) {
402				return false;
403			}
404		}
405	},
406
407	// https://ecma-international.org/ecma-262/6.0/#sec-hasownproperty
408	HasOwnProperty: function HasOwnProperty(O, P) {
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		return has(O, P);
416	},
417
418	// https://ecma-international.org/ecma-262/6.0/#sec-hasproperty
419	HasProperty: function HasProperty(O, P) {
420		if (this.Type(O) !== 'Object') {
421			throw new $TypeError('O must be an Object');
422		}
423		if (!this.IsPropertyKey(P)) {
424			throw new $TypeError('P must be a Property Key');
425		}
426		return P in O;
427	},
428
429	// https://ecma-international.org/ecma-262/6.0/#sec-isconcatspreadable
430	IsConcatSpreadable: function IsConcatSpreadable(O) {
431		if (this.Type(O) !== 'Object') {
432			return false;
433		}
434		if (hasSymbols && typeof $Symbol.isConcatSpreadable === 'symbol') {
435			var spreadable = this.Get(O, Symbol.isConcatSpreadable);
436			if (typeof spreadable !== 'undefined') {
437				return this.ToBoolean(spreadable);
438			}
439		}
440		return this.IsArray(O);
441	},
442
443	// https://ecma-international.org/ecma-262/6.0/#sec-invoke
444	Invoke: function Invoke(O, P) {
445		if (!this.IsPropertyKey(P)) {
446			throw new $TypeError('P must be a Property Key');
447		}
448		var argumentsList = arraySlice(arguments, 2);
449		var func = this.GetV(O, P);
450		return this.Call(func, O, argumentsList);
451	},
452
453	// https://ecma-international.org/ecma-262/6.0/#sec-getiterator
454	GetIterator: function GetIterator(obj, method) {
455		if (!hasSymbols) {
456			throw new SyntaxError('ES.GetIterator depends on native iterator support.');
457		}
458
459		var actualMethod = method;
460		if (arguments.length < 2) {
461			actualMethod = this.GetMethod(obj, $Symbol.iterator);
462		}
463		var iterator = this.Call(actualMethod, obj);
464		if (this.Type(iterator) !== 'Object') {
465			throw new $TypeError('iterator must return an object');
466		}
467
468		return iterator;
469	},
470
471	// https://ecma-international.org/ecma-262/6.0/#sec-iteratornext
472	IteratorNext: function IteratorNext(iterator, value) {
473		var result = this.Invoke(iterator, 'next', arguments.length < 2 ? [] : [value]);
474		if (this.Type(result) !== 'Object') {
475			throw new $TypeError('iterator next must return an object');
476		}
477		return result;
478	},
479
480	// https://ecma-international.org/ecma-262/6.0/#sec-iteratorcomplete
481	IteratorComplete: function IteratorComplete(iterResult) {
482		if (this.Type(iterResult) !== 'Object') {
483			throw new $TypeError('Assertion failed: Type(iterResult) is not Object');
484		}
485		return this.ToBoolean(this.Get(iterResult, 'done'));
486	},
487
488	// https://ecma-international.org/ecma-262/6.0/#sec-iteratorvalue
489	IteratorValue: function IteratorValue(iterResult) {
490		if (this.Type(iterResult) !== 'Object') {
491			throw new $TypeError('Assertion failed: Type(iterResult) is not Object');
492		}
493		return this.Get(iterResult, 'value');
494	},
495
496	// https://ecma-international.org/ecma-262/6.0/#sec-iteratorstep
497	IteratorStep: function IteratorStep(iterator) {
498		var result = this.IteratorNext(iterator);
499		var done = this.IteratorComplete(result);
500		return done === true ? false : result;
501	},
502
503	// https://ecma-international.org/ecma-262/6.0/#sec-iteratorclose
504	IteratorClose: function IteratorClose(iterator, completion) {
505		if (this.Type(iterator) !== 'Object') {
506			throw new $TypeError('Assertion failed: Type(iterator) is not Object');
507		}
508		if (!this.IsCallable(completion)) {
509			throw new $TypeError('Assertion failed: completion is not a thunk for a Completion Record');
510		}
511		var completionThunk = completion;
512
513		var iteratorReturn = this.GetMethod(iterator, 'return');
514
515		if (typeof iteratorReturn === 'undefined') {
516			return completionThunk();
517		}
518
519		var completionRecord;
520		try {
521			var innerResult = this.Call(iteratorReturn, iterator, []);
522		} catch (e) {
523			// if we hit here, then "e" is the innerResult completion that needs re-throwing
524
525			// if the completion is of type "throw", this will throw.
526			completionRecord = completionThunk();
527			completionThunk = null; // ensure it's not called twice.
528
529			// if not, then return the innerResult completion
530			throw e;
531		}
532		completionRecord = completionThunk(); // if innerResult worked, then throw if the completion does
533		completionThunk = null; // ensure it's not called twice.
534
535		if (this.Type(innerResult) !== 'Object') {
536			throw new $TypeError('iterator .return must return an object');
537		}
538
539		return completionRecord;
540	},
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
553	// https://ecma-international.org/ecma-262/6.0/#sec-regexpexec
554	RegExpExec: function RegExpExec(R, S) {
555		if (this.Type(R) !== 'Object') {
556			throw new $TypeError('R must be an Object');
557		}
558		if (this.Type(S) !== 'String') {
559			throw new $TypeError('S must be a String');
560		}
561		var exec = this.Get(R, 'exec');
562		if (this.IsCallable(exec)) {
563			var result = this.Call(exec, R, [S]);
564			if (result === null || this.Type(result) === 'Object') {
565				return result;
566			}
567			throw new $TypeError('"exec" method must return `null` or an Object');
568		}
569		return regexExec(R, S);
570	},
571
572	// https://ecma-international.org/ecma-262/6.0/#sec-arrayspeciescreate
573	ArraySpeciesCreate: function ArraySpeciesCreate(originalArray, length) {
574		if (!this.IsInteger(length) || length < 0) {
575			throw new $TypeError('Assertion failed: length must be an integer >= 0');
576		}
577		var len = length === 0 ? 0 : length;
578		var C;
579		var isArray = this.IsArray(originalArray);
580		if (isArray) {
581			C = this.Get(originalArray, 'constructor');
582			// TODO: figure out how to make a cross-realm normal Array, a same-realm Array
583			// if (this.IsConstructor(C)) {
584			// 	if C is another realm's Array, C = undefined
585			// 	Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Array))) === null ?
586			// }
587			if (this.Type(C) === 'Object' && hasSymbols && $Symbol.species) {
588				C = this.Get(C, $Symbol.species);
589				if (C === null) {
590					C = void 0;
591				}
592			}
593		}
594		if (typeof C === 'undefined') {
595			return $Array(len);
596		}
597		if (!this.IsConstructor(C)) {
598			throw new $TypeError('C must be a constructor');
599		}
600		return new C(len); // this.Construct(C, len);
601	},
602
603	CreateDataProperty: function CreateDataProperty(O, P, V) {
604		if (this.Type(O) !== 'Object') {
605			throw new $TypeError('Assertion failed: Type(O) is not Object');
606		}
607		if (!this.IsPropertyKey(P)) {
608			throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
609		}
610		var oldDesc = $gOPD(O, P);
611		var extensible = oldDesc || (typeof $isExtensible !== 'function' || $isExtensible(O));
612		var immutable = oldDesc && (!oldDesc.writable || !oldDesc.configurable);
613		if (immutable || !extensible) {
614			return false;
615		}
616		var newDesc = {
617			configurable: true,
618			enumerable: true,
619			value: V,
620			writable: true
621		};
622		Object.defineProperty(O, P, newDesc);
623		return true;
624	},
625
626	// https://ecma-international.org/ecma-262/6.0/#sec-createdatapropertyorthrow
627	CreateDataPropertyOrThrow: function CreateDataPropertyOrThrow(O, P, V) {
628		if (this.Type(O) !== 'Object') {
629			throw new $TypeError('Assertion failed: Type(O) is not Object');
630		}
631		if (!this.IsPropertyKey(P)) {
632			throw new $TypeError('Assertion failed: IsPropertyKey(P) is not true');
633		}
634		var success = this.CreateDataProperty(O, P, V);
635		if (!success) {
636			throw new $TypeError('unable to create data property');
637		}
638		return success;
639	},
640
641	// https://www.ecma-international.org/ecma-262/6.0/#sec-objectcreate
642	ObjectCreate: function ObjectCreate(proto, internalSlotsList) {
643		if (proto !== null && this.Type(proto) !== 'Object') {
644			throw new $TypeError('Assertion failed: proto must be null or an object');
645		}
646		var slots = arguments.length < 2 ? [] : internalSlotsList;
647		if (slots.length > 0) {
648			throw new $SyntaxError('es-abstract does not yet support internal slots');
649		}
650
651		if (proto === null && !$ObjectCreate) {
652			throw new $SyntaxError('native Object.create support is required to create null objects');
653		}
654
655		return $ObjectCreate(proto);
656	},
657
658	// https://ecma-international.org/ecma-262/6.0/#sec-advancestringindex
659	AdvanceStringIndex: function AdvanceStringIndex(S, index, unicode) {
660		if (this.Type(S) !== 'String') {
661			throw new $TypeError('S must be a String');
662		}
663		if (!this.IsInteger(index) || index < 0 || index > MAX_SAFE_INTEGER) {
664			throw new $TypeError('Assertion failed: length must be an integer >= 0 and <= 2**53');
665		}
666		if (this.Type(unicode) !== 'Boolean') {
667			throw new $TypeError('Assertion failed: unicode must be a Boolean');
668		}
669		if (!unicode) {
670			return index + 1;
671		}
672		var length = S.length;
673		if ((index + 1) >= length) {
674			return index + 1;
675		}
676
677		var first = $charCodeAt(S, index);
678		if (first < 0xD800 || first > 0xDBFF) {
679			return index + 1;
680		}
681
682		var second = $charCodeAt(S, index + 1);
683		if (second < 0xDC00 || second > 0xDFFF) {
684			return index + 1;
685		}
686
687		return index + 2;
688	}
689});
690
691delete ES6.CheckObjectCoercible; // renamed in ES6 to RequireObjectCoercible
692
693module.exports = ES6;
694