Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/js/array.js b/src/js/array.js
index 1406df3..0a77b23 100644
--- a/src/js/array.js
+++ b/src/js/array.js
@@ -11,7 +11,6 @@
// -------------------------------------------------------------------
// Imports
-var AddIndexedProperty;
var FLAG_harmony_species;
var GetIterator;
var GetMethod;
@@ -21,27 +20,18 @@
var MakeTypeError;
var MaxSimple;
var MinSimple;
-var ObjectDefineProperty;
var ObjectHasOwnProperty;
var ObjectToString = utils.ImportNow("object_to_string");
-var ObserveBeginPerformSplice;
-var ObserveEndPerformSplice;
-var ObserveEnqueueSpliceRecord;
var iteratorSymbol = utils.ImportNow("iterator_symbol");
var unscopablesSymbol = utils.ImportNow("unscopables_symbol");
utils.Import(function(from) {
- AddIndexedProperty = from.AddIndexedProperty;
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
MakeTypeError = from.MakeTypeError;
MaxSimple = from.MaxSimple;
MinSimple = from.MinSimple;
- ObjectDefineProperty = from.ObjectDefineProperty;
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
- ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
- ObserveEndPerformSplice = from.ObserveEndPerformSplice;
- ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
});
utils.ImportFromExperimental(function(from) {
@@ -53,6 +43,9 @@
function ArraySpeciesCreate(array, length) {
var constructor;
+
+ length = INVERT_NEG_ZERO(length);
+
if (FLAG_harmony_species) {
constructor = %ArraySpeciesConstructor(array);
} else {
@@ -62,17 +55,6 @@
}
-function DefineIndexedProperty(array, i, value) {
- if (FLAG_harmony_species) {
- var result = ObjectDefineProperty(array, i, {
- value: value, writable: true, configurable: true, enumerable: true
- });
- if (!result) throw MakeTypeError(kStrictCannotAssign, i);
- } else {
- AddIndexedProperty(array, i, value);
- }
-}
-
function KeySortCompare(a, b) {
return a - b;
}
@@ -123,8 +105,7 @@
// Only use the sparse variant on arrays that are likely to be sparse and the
// number of elements touched in the operation is relatively small compared to
// the overall size of the array.
- if (!is_array || length < 1000 || %IsObserved(array) ||
- %HasComplexElements(array)) {
+ if (!is_array || length < 1000 || %HasComplexElements(array)) {
return false;
}
if (!%_IsSmi(length)) {
@@ -265,7 +246,7 @@
for (var i = start_i; i < limit; ++i) {
var current = array[i];
if (!IS_UNDEFINED(current) || i in array) {
- DefineIndexedProperty(deleted_elements, i - start_i, current);
+ %CreateDataProperty(deleted_elements, i - start_i, current);
}
}
} else {
@@ -275,7 +256,7 @@
if (key >= start_i) {
var current = array[key];
if (!IS_UNDEFINED(current) || key in array) {
- DefineIndexedProperty(deleted_elements, key - start_i, current);
+ %CreateDataProperty(deleted_elements, key - start_i, current);
}
}
}
@@ -352,7 +333,7 @@
var index = start_i + i;
if (HAS_INDEX(array, index, is_array)) {
var current = array[index];
- DefineIndexedProperty(deleted_elements, i, current);
+ %CreateDataProperty(deleted_elements, i, current);
}
}
}
@@ -456,23 +437,6 @@
}
-function ObservedArrayPop(n) {
- n--;
- var value = this[n];
-
- try {
- ObserveBeginPerformSplice(this);
- delete this[n];
- this.length = n;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, n, [value], 0);
- }
-
- return value;
-}
-
-
// Removes the last element from the array and returns it. See
// ECMA-262, section 15.4.4.6.
function ArrayPop() {
@@ -485,9 +449,6 @@
return;
}
- if (%IsObserved(array))
- return ObservedArrayPop.call(array, n);
-
n--;
var value = array[n];
%DeleteProperty_Strict(array, n);
@@ -496,46 +457,19 @@
}
-function ObservedArrayPush() {
- var n = TO_LENGTH(this.length);
- var m = arguments.length;
-
- try {
- ObserveBeginPerformSplice(this);
- for (var i = 0; i < m; i++) {
- this[i+n] = arguments[i];
- }
- var new_length = n + m;
- this.length = new_length;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, n, [], m);
- }
-
- return new_length;
-}
-
-
// Appends the arguments to the end of the array and returns the new
// length of the array. See ECMA-262, section 15.4.4.7.
function ArrayPush() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.push");
- if (%IsObserved(this))
- return ObservedArrayPush.apply(this, arguments);
-
var array = TO_OBJECT(this);
var n = TO_LENGTH(array.length);
var m = arguments.length;
- // It appears that there is no enforced, absolute limit on the number of
- // arguments, but it would surely blow the stack to use 2**30 or more.
- // To avoid integer overflow, do the comparison to the max safe integer
- // after subtracting 2**30 from both sides. (2**31 would seem like a
- // natural value, but it is negative in JS, and 2**32 is 1.)
- if (m > (1 << 30) || (n - (1 << 30)) + m > kMaxSafeInteger - (1 << 30)) {
- throw MakeTypeError(kPushPastSafeLength, m, n);
- }
+ // Subtract n from kMaxSafeInteger rather than testing m + n >
+ // kMaxSafeInteger. n may already be kMaxSafeInteger. In that case adding
+ // e.g., 1 would not be safe.
+ if (m > kMaxSafeInteger - n) throw MakeTypeError(kPushPastSafeLength, m, n);
for (var i = 0; i < m; i++) {
array[i+n] = arguments[i];
@@ -646,22 +580,6 @@
}
-function ObservedArrayShift(len) {
- var first = this[0];
-
- try {
- ObserveBeginPerformSplice(this);
- SimpleMove(this, 0, 1, len, 0);
- this.length = len - 1;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, 0, [first], 0);
- }
-
- return first;
-}
-
-
function ArrayShift() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
@@ -675,9 +593,6 @@
if (%object_is_sealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed);
- if (%IsObserved(array))
- return ObservedArrayShift.call(array, len);
-
var first = array[0];
if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
@@ -692,33 +607,9 @@
}
-function ObservedArrayUnshift() {
- var len = TO_LENGTH(this.length);
- var num_arguments = arguments.length;
-
- try {
- ObserveBeginPerformSplice(this);
- SimpleMove(this, 0, 0, len, num_arguments);
- for (var i = 0; i < num_arguments; i++) {
- this[i] = arguments[i];
- }
- var new_length = len + num_arguments;
- this.length = new_length;
- } finally {
- ObserveEndPerformSplice(this);
- ObserveEnqueueSpliceRecord(this, 0, [], num_arguments);
- }
-
- return new_length;
-}
-
-
function ArrayUnshift(arg1) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
- if (%IsObserved(this))
- return ObservedArrayUnshift.apply(this, arguments);
-
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
var num_arguments = arguments.length;
@@ -813,53 +704,9 @@
}
-function ObservedArraySplice(start, delete_count) {
- var num_arguments = arguments.length;
- var len = TO_LENGTH(this.length);
- var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len);
- var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len,
- start_i);
- var deleted_elements = [];
- deleted_elements.length = del_count;
- var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0;
-
- try {
- ObserveBeginPerformSplice(this);
-
- SimpleSlice(this, start_i, del_count, len, deleted_elements);
- SimpleMove(this, start_i, del_count, len, num_elements_to_add);
-
- // Insert the arguments into the resulting array in
- // place of the deleted elements.
- var i = start_i;
- var arguments_index = 2;
- var arguments_length = arguments.length;
- while (arguments_index < arguments_length) {
- this[i++] = arguments[arguments_index++];
- }
- this.length = len - del_count + num_elements_to_add;
-
- } finally {
- ObserveEndPerformSplice(this);
- if (deleted_elements.length || num_elements_to_add) {
- ObserveEnqueueSpliceRecord(this,
- start_i,
- deleted_elements.slice(),
- num_elements_to_add);
- }
- }
-
- // Return the deleted elements.
- return deleted_elements;
-}
-
-
function ArraySplice(start, delete_count) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.splice");
- if (%IsObserved(this))
- return ObservedArraySplice.apply(this, arguments);
-
var num_arguments = arguments.length;
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length);
@@ -1048,7 +895,8 @@
// of a prototype property.
var CopyFromPrototype = function CopyFromPrototype(obj, length) {
var max = 0;
- for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+ for (var proto = %object_get_prototype_of(obj); proto;
+ proto = %object_get_prototype_of(proto)) {
var indices = IS_PROXY(proto) ? length : %GetArrayKeys(proto, length);
if (IS_NUMBER(indices)) {
// It's an interval.
@@ -1076,7 +924,8 @@
// where a prototype of obj has an element. I.e., shadow all prototype
// elements in that range.
var ShadowPrototypeElements = function(obj, from, to) {
- for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
+ for (var proto = %object_get_prototype_of(obj); proto;
+ proto = %object_get_prototype_of(proto)) {
var indices = IS_PROXY(proto) ? to : %GetArrayKeys(proto, to);
if (IS_NUMBER(indices)) {
// It's an interval.
@@ -1143,7 +992,7 @@
}
for (i = length - num_holes; i < length; i++) {
// For compatability with Webkit, do not expose elements in the prototype.
- if (i in %_GetPrototype(obj)) {
+ if (i in %object_get_prototype_of(obj)) {
obj[i] = UNDEFINED;
} else {
delete obj[i];
@@ -1174,9 +1023,9 @@
var num_non_undefined = %RemoveArrayHoles(array, length);
if (num_non_undefined == -1) {
- // The array is observed, or there were indexed accessors in the array.
+ // There were indexed accessors in the array.
// Move array holes and undefineds to the end using a Javascript function
- // that is safe in the presence of accessors and is observable.
+ // that is safe in the presence of accessors.
num_non_undefined = SafeRemoveArrayHoles(array);
}
@@ -1211,7 +1060,7 @@
if (HAS_INDEX(array, i, is_array)) {
var element = array[i];
if (%_Call(f, receiver, element, i, array)) {
- DefineIndexedProperty(result, result_length, element);
+ %CreateDataProperty(result, result_length, element);
result_length++;
}
}
@@ -1331,7 +1180,7 @@
for (var i = 0; i < length; i++) {
if (HAS_INDEX(array, i, is_array)) {
var element = array[i];
- DefineIndexedProperty(result, i, %_Call(f, receiver, element, i, array));
+ %CreateDataProperty(result, i, %_Call(f, receiver, element, i, array));
}
}
return result;
@@ -1347,7 +1196,7 @@
if (IS_UNDEFINED(index)) {
index = 0;
} else {
- index = TO_INTEGER(index) + 0; // Add 0 to convert -0 to 0
+ index = INVERT_NEG_ZERO(TO_INTEGER(index));
// If index is negative, index from the end of the array.
if (index < 0) {
index = length + index;
@@ -1409,7 +1258,7 @@
if (argumentsLength < 2) {
index = length - 1;
} else {
- index = TO_INTEGER(index) + 0; // Add 0 to convert -0 to 0
+ index = INVERT_NEG_ZERO(TO_INTEGER(index));
// If index is negative, index from end of the array.
if (index < 0) index += length;
// If index is still negative, do not search the array.
@@ -1736,17 +1585,6 @@
}
-function AddArrayElement(constructor, array, i, value) {
- if (constructor === GlobalArray) {
- AddIndexedProperty(array, i, value);
- } else {
- ObjectDefineProperty(array, i, {
- value: value, writable: true, configurable: true, enumerable: true
- });
- }
-}
-
-
// ES6, draft 10-14-14, section 22.1.2.1
function ArrayFrom(arrayLike, mapfn, receiver) {
var items = TO_OBJECT(arrayLike);
@@ -1775,7 +1613,7 @@
} else {
mappedValue = nextValue;
}
- AddArrayElement(this, result, k, mappedValue);
+ %CreateDataProperty(result, k, mappedValue);
k++;
}
result.length = k;
@@ -1791,7 +1629,7 @@
} else {
mappedValue = nextValue;
}
- AddArrayElement(this, result, k, mappedValue);
+ %CreateDataProperty(result, k, mappedValue);
}
result.length = k;
@@ -1807,7 +1645,7 @@
// TODO: Implement IsConstructor (ES6 section 7.2.5)
var array = %IsConstructor(constructor) ? new constructor(length) : [];
for (var i = 0; i < length; i++) {
- AddArrayElement(constructor, array, i, args[i]);
+ %CreateDataProperty(array, i, args[i]);
}
array.length = length;
return array;
diff --git a/src/js/arraybuffer.js b/src/js/arraybuffer.js
index f0273c7..e739960 100644
--- a/src/js/arraybuffer.js
+++ b/src/js/arraybuffer.js
@@ -70,7 +70,9 @@
throw MakeTypeError(kIncompatibleMethodReceiver,
'ArrayBuffer.prototype.slice', result);
}
- // TODO(littledan): Check for a detached ArrayBuffer
+ // Checks for detached source/target ArrayBuffers are done inside of
+ // %ArrayBufferSliceImpl; the reordering of checks does not violate
+ // the spec because all exceptions thrown are TypeErrors.
if (result === this) {
throw MakeTypeError(kArrayBufferSpeciesThis);
}
diff --git a/src/js/generator.js b/src/js/generator.js
deleted file mode 100644
index 3dcdcc0..0000000
--- a/src/js/generator.js
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-// -------------------------------------------------------------------
-// Imports
-
-var GeneratorFunctionPrototype = utils.ImportNow("GeneratorFunctionPrototype");
-var GeneratorFunction = utils.ImportNow("GeneratorFunction");
-var GlobalFunction = global.Function;
-var MakeTypeError;
-var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
-
-utils.Import(function(from) {
- MakeTypeError = from.MakeTypeError;
-});
-
-// ----------------------------------------------------------------------------
-
-// Generator functions and objects are specified by ES6, sections 15.19.3 and
-// 15.19.4.
-
-function GeneratorObjectNext(value) {
- if (!IS_GENERATOR(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- '[Generator].prototype.next', this);
- }
-
- var continuation = %GeneratorGetContinuation(this);
- if (continuation > 0) {
- // Generator is suspended.
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
- return %_GeneratorNext(this, value);
- } else if (continuation == 0) {
- // Generator is already closed.
- return %_CreateIterResultObject(UNDEFINED, true);
- } else {
- // Generator is running.
- throw MakeTypeError(kGeneratorRunning);
- }
-}
-
-
-function GeneratorObjectReturn(value) {
- if (!IS_GENERATOR(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- '[Generator].prototype.return', this);
- }
-
- var continuation = %GeneratorGetContinuation(this);
- if (continuation > 0) {
- // Generator is suspended.
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
- return %_GeneratorReturn(this, value);
- } else if (continuation == 0) {
- // Generator is already closed.
- return %_CreateIterResultObject(value, true);
- } else {
- // Generator is running.
- throw MakeTypeError(kGeneratorRunning);
- }
-}
-
-
-function GeneratorObjectThrow(exn) {
- if (!IS_GENERATOR(this)) {
- throw MakeTypeError(kIncompatibleMethodReceiver,
- '[Generator].prototype.throw', this);
- }
-
- var continuation = %GeneratorGetContinuation(this);
- if (continuation > 0) {
- // Generator is suspended.
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(this);
- return %_GeneratorThrow(this, exn);
- } else if (continuation == 0) {
- // Generator is already closed.
- throw exn;
- } else {
- // Generator is running.
- throw MakeTypeError(kGeneratorRunning);
- }
-}
-
-// ----------------------------------------------------------------------------
-
-// None of the three resume operations (Runtime_GeneratorNext,
-// Runtime_GeneratorReturn, Runtime_GeneratorThrow) is supported by
-// Crankshaft or TurboFan. Disable optimization of wrappers here.
-%NeverOptimizeFunction(GeneratorObjectNext);
-%NeverOptimizeFunction(GeneratorObjectReturn);
-%NeverOptimizeFunction(GeneratorObjectThrow);
-
-// Set up non-enumerable functions on the generator prototype object.
-var GeneratorObjectPrototype = GeneratorFunctionPrototype.prototype;
-utils.InstallFunctions(GeneratorObjectPrototype,
- DONT_ENUM,
- ["next", GeneratorObjectNext,
- "return", GeneratorObjectReturn,
- "throw", GeneratorObjectThrow]);
-
-%AddNamedProperty(GeneratorObjectPrototype, "constructor",
- GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
-%AddNamedProperty(GeneratorObjectPrototype,
- toStringTagSymbol, "Generator", DONT_ENUM | READ_ONLY);
-%InternalSetPrototype(GeneratorFunctionPrototype, GlobalFunction.prototype);
-%AddNamedProperty(GeneratorFunctionPrototype,
- toStringTagSymbol, "GeneratorFunction", DONT_ENUM | READ_ONLY);
-%AddNamedProperty(GeneratorFunctionPrototype, "constructor",
- GeneratorFunction, DONT_ENUM | READ_ONLY);
-%InternalSetPrototype(GeneratorFunction, GlobalFunction);
-
-})
diff --git a/src/js/harmony-async-await.js b/src/js/harmony-async-await.js
new file mode 100644
index 0000000..c6705ef
--- /dev/null
+++ b/src/js/harmony-async-await.js
@@ -0,0 +1,43 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils, extrasUtils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var AsyncFunctionNext;
+var AsyncFunctionThrow;
+var PromiseReject;
+var PromiseResolve;
+var PromiseThen;
+
+utils.Import(function(from) {
+ AsyncFunctionNext = from.AsyncFunctionNext;
+ AsyncFunctionThrow = from.AsyncFunctionThrow;
+ PromiseReject = from.PromiseCreateRejected;
+ PromiseResolve = from.PromiseCreateResolved;
+ PromiseThen = from.PromiseThen;
+});
+
+// -------------------------------------------------------------------
+
+function AsyncFunctionAwait(generator, value) {
+ return %_Call(
+ PromiseThen, PromiseResolve(value),
+ function(sentValue) {
+ return %_Call(AsyncFunctionNext, generator, sentValue);
+ },
+ function(sentError) {
+ return %_Call(AsyncFunctionThrow, generator, sentError);
+ });
+}
+
+%InstallToContext([ "async_function_await", AsyncFunctionAwait ]);
+
+})
diff --git a/src/js/harmony-atomics.js b/src/js/harmony-atomics.js
index 9f80227..8372903 100644
--- a/src/js/harmony-atomics.js
+++ b/src/js/harmony-atomics.js
@@ -62,19 +62,6 @@
return %_AtomicsCompareExchange(sta, index, oldValue, newValue);
}
-function AtomicsLoadJS(sta, index) {
- CheckSharedIntegerTypedArray(sta);
- index = ValidateIndex(index, %_TypedArrayGetLength(sta));
- return %_AtomicsLoad(sta, index);
-}
-
-function AtomicsStoreJS(sta, index, value) {
- CheckSharedIntegerTypedArray(sta);
- index = ValidateIndex(index, %_TypedArrayGetLength(sta));
- value = TO_NUMBER(value);
- return %_AtomicsStore(sta, index, value);
-}
-
function AtomicsAddJS(ia, index, value) {
CheckSharedIntegerTypedArray(ia);
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
@@ -161,13 +148,9 @@
// -------------------------------------------------------------------
-function AtomicsConstructor() {}
+var Atomics = global.Atomics;
-var Atomics = new AtomicsConstructor();
-
-%InternalSetPrototype(Atomics, GlobalObject.prototype);
-%AddNamedProperty(global, "Atomics", Atomics, DONT_ENUM);
-%FunctionSetInstanceClassName(AtomicsConstructor, 'Atomics');
+// The Atomics global is defined by the bootstrapper.
%AddNamedProperty(Atomics, toStringTagSymbol, "Atomics", READ_ONLY | DONT_ENUM);
@@ -179,9 +162,9 @@
]);
utils.InstallFunctions(Atomics, DONT_ENUM, [
+ // TODO(binji): remove the rest of the (non futex) Atomics functions as they
+ // become builtins.
"compareExchange", AtomicsCompareExchangeJS,
- "load", AtomicsLoadJS,
- "store", AtomicsStoreJS,
"add", AtomicsAddJS,
"sub", AtomicsSubJS,
"and", AtomicsAndJS,
diff --git a/src/js/harmony-object-observe.js b/src/js/harmony-object-observe.js
deleted file mode 100644
index 95dd298..0000000
--- a/src/js/harmony-object-observe.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-var ObserveArrayMethods = utils.ImportNow("ObserveArrayMethods");
-var ObserveObjectMethods = utils.ImportNow("ObserveObjectMethods");;
-
-utils.InstallFunctions(global.Object, DONT_ENUM, ObserveObjectMethods);
-utils.InstallFunctions(global.Array, DONT_ENUM, ObserveArrayMethods);
-
-})
diff --git a/src/js/harmony-string-padding.js b/src/js/harmony-string-padding.js
index a6c6c47..dc59823 100644
--- a/src/js/harmony-string-padding.js
+++ b/src/js/harmony-string-padding.js
@@ -30,7 +30,8 @@
} else {
fillString = TO_STRING(fillString);
if (fillString === "") {
- fillString = " ";
+ // If filler is the empty String, return S.
+ return "";
}
}
diff --git a/src/js/i18n.js b/src/js/i18n.js
index 845289a..7c9535b 100644
--- a/src/js/i18n.js
+++ b/src/js/i18n.js
@@ -20,6 +20,7 @@
var ArrayIndexOf;
var ArrayJoin;
var ArrayPush;
+var FLAG_intl_extra;
var GlobalBoolean = global.Boolean;
var GlobalDate = global.Date;
var GlobalNumber = global.Number;
@@ -27,7 +28,7 @@
var GlobalString = global.String;
var InstallFunctions = utils.InstallFunctions;
var InstallGetter = utils.InstallGetter;
-var InternalPackedArray = utils.InternalPackedArray;
+var InternalArray = utils.InternalArray;
var InternalRegExpMatch;
var InternalRegExpReplace
var IsFinite;
@@ -35,8 +36,6 @@
var MakeError;
var MakeRangeError;
var MakeTypeError;
-var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties");
-var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty");
var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
var OverrideFunction = utils.OverrideFunction;
var patternSymbol = utils.ImportNow("intl_pattern_symbol");
@@ -66,6 +65,10 @@
StringSubstring = from.StringSubstring;
});
+utils.ImportFromExperimental(function(from) {
+ FLAG_intl_extra = from.FLAG_intl_extra;
+});
+
// Utilities for definitions
function InstallFunction(object, name, func) {
@@ -84,11 +87,11 @@
/**
* Adds bound method to the prototype of the given object.
*/
-function AddBoundMethod(obj, methodName, implementation, length) {
+function AddBoundMethod(obj, methodName, implementation, length, type) {
%CheckIsBootstrapping();
var internalName = %CreatePrivateSymbol(methodName);
var getter = function() {
- if (!%IsInitializedIntlObject(this)) {
+ if (!%IsInitializedIntlObjectOfType(this, type)) {
throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
}
if (IS_UNDEFINED(this[internalName])) {
@@ -144,6 +147,13 @@
*/
var DEFAULT_ICU_LOCALE = UNDEFINED;
+function GetDefaultICULocaleJS() {
+ if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
+ DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+ }
+ return DEFAULT_ICU_LOCALE;
+}
+
/**
* Unicode extension regular expression.
*/
@@ -307,7 +317,7 @@
* Locales appear in the same order in the returned list as in the input list.
*/
function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
- var matchedLocales = [];
+ var matchedLocales = new InternalArray();
for (var i = 0; i < requestedLocales.length; ++i) {
// Remove -u- extension.
var locale = InternalRegExpReplace(
@@ -448,11 +458,7 @@
}
// Didn't find a match, return default.
- if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
- DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
- }
-
- return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+ return {'locale': GetDefaultICULocaleJS(), 'extension': '', 'position': -1};
}
@@ -567,21 +573,23 @@
/**
- * Converts all OwnProperties into
+ * Given an array-like, outputs an Array with the numbered
+ * properties copied over and defined
* configurable: false, writable: false, enumerable: true.
*/
-function freezeArray(array) {
- var l = array.length;
+function freezeArray(input) {
+ var array = [];
+ var l = input.length;
for (var i = 0; i < l; i++) {
- if (i in array) {
- ObjectDefineProperty(array, i, {value: array[i],
- configurable: false,
- writable: false,
- enumerable: true});
+ if (i in input) {
+ %object_define_property(array, i, {value: input[i],
+ configurable: false,
+ writable: false,
+ enumerable: true});
}
}
- ObjectDefineProperty(array, 'length', {value: l, writable: false});
+ %object_define_property(array, 'length', {value: l, writable: false});
return array;
}
@@ -643,8 +651,8 @@
* Configurable is false by default.
*/
function defineWEProperty(object, property, value) {
- ObjectDefineProperty(object, property,
- {value: value, writable: true, enumerable: true});
+ %object_define_property(object, property,
+ {value: value, writable: true, enumerable: true});
}
@@ -663,10 +671,10 @@
* Defines a property and sets writable, enumerable and configurable to true.
*/
function defineWECProperty(object, property, value) {
- ObjectDefineProperty(object, property, {value: value,
- writable: true,
- enumerable: true,
- configurable: true});
+ %object_define_property(object, property, {value: value,
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
@@ -722,21 +730,24 @@
*/
function canonicalizeLanguageTag(localeID) {
// null is typeof 'object' so we have to do extra check.
- if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+ if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) ||
IS_NULL(localeID)) {
throw MakeTypeError(kLanguageID);
}
+ // Optimize for the most common case; a language code alone in
+ // the canonical form/lowercase (e.g. "en", "fil").
+ if (IS_STRING(localeID) &&
+ !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) {
+ return localeID;
+ }
+
var localeString = GlobalString(localeID);
if (isValidLanguageTag(localeString) === false) {
throw MakeRangeError(kInvalidLanguageTag, localeString);
}
- // This call will strip -kn but not -kn-true extensions.
- // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
- // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
- // upgrade to ICU 4.9.
var tag = %CanonicalizeLanguageTag(localeString);
if (tag === 'invalid-tag') {
throw MakeRangeError(kInvalidLanguageTag, localeString);
@@ -751,11 +762,8 @@
* Throws on locales that are not well formed BCP47 tags.
*/
function initializeLocaleList(locales) {
- var seen = [];
- if (IS_UNDEFINED(locales)) {
- // Constructor is called without arguments.
- seen = [];
- } else {
+ var seen = new InternalArray();
+ if (!IS_UNDEFINED(locales)) {
// We allow single string localeID.
if (typeof locales === 'string') {
%_Call(ArrayPush, seen, canonicalizeLanguageTag(locales));
@@ -810,8 +818,8 @@
// Skip language since it can match variant regex, so we start from 1.
// We are matching i-klingon here, but that's ok, since i-klingon-klingon
// is not valid and would fail LANGUAGE_TAG_RE test.
- var variants = [];
- var extensions = [];
+ var variants = new InternalArray();
+ var extensions = new InternalArray();
var parts = %_Call(StringSplit, locale, '-');
for (var i = 1; i < parts.length; i++) {
var value = parts[i];
@@ -965,8 +973,8 @@
// We define all properties C++ code may produce, to prevent security
// problems. If malicious user decides to redefine Object.prototype.locale
// we can't just use plain x.locale = 'us' or in C++ Set("locale", "us").
- // ObjectDefineProperties will either succeed defining or throw an error.
- var resolved = ObjectDefineProperties({}, {
+ // %object_define_properties will either succeed defining or throw an error.
+ var resolved = %object_define_properties({}, {
caseFirst: {writable: true},
collation: {value: internalOptions.collation, writable: true},
ignorePunctuation: {writable: true},
@@ -985,7 +993,9 @@
// Writable, configurable and enumerable are set to false by default.
%MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator);
collator[resolvedSymbol] = resolved;
- ObjectDefineProperty(collator, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(collator, 'resolved', resolvedAccessor);
+ }
return collator;
}
@@ -1072,7 +1082,7 @@
};
-AddBoundMethod(Intl.Collator, 'compare', compare, 2);
+AddBoundMethod(Intl.Collator, 'compare', compare, 2, 'collator');
/**
* Verifies that the input is a well-formed ISO 4217 currency code.
@@ -1198,7 +1208,7 @@
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
currency: {writable: true},
currencyDisplay: {writable: true},
locale: {writable: true},
@@ -1206,7 +1216,6 @@
minimumFractionDigits: {writable: true},
minimumIntegerDigits: {writable: true},
numberingSystem: {writable: true},
- pattern: patternAccessor,
requestedLocale: {value: requestedLocale, writable: true},
style: {value: internalOptions.style, writable: true},
useGrouping: {writable: true}
@@ -1222,13 +1231,16 @@
resolved);
if (internalOptions.style === 'currency') {
- ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
- writable: true});
+ %object_define_property(resolved, 'currencyDisplay',
+ {value: currencyDisplay, writable: true});
}
%MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter);
numberFormat[resolvedSymbol] = resolved;
- ObjectDefineProperty(numberFormat, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(resolved, 'pattern', patternAccessor);
+ %object_define_property(numberFormat, 'resolved', resolvedAccessor);
+ }
return numberFormat;
}
@@ -1334,14 +1346,12 @@
/**
* Returns a Number that represents string value that was passed in.
*/
-function parseNumber(formatter, value) {
+function IntlParseNumber(formatter, value) {
return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
GlobalString(value));
}
-
-AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
-AddBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
+AddBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1, 'numberformat');
/**
* Returns a string that matches LDML representation of the options object.
@@ -1508,33 +1518,33 @@
}
if (needsDefault && (defaults === 'date' || defaults === 'all')) {
- ObjectDefineProperty(options, 'year', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'month', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'day', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
+ %object_define_property(options, 'year', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'month', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'day', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
if (needsDefault && (defaults === 'time' || defaults === 'all')) {
- ObjectDefineProperty(options, 'hour', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'minute', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
- ObjectDefineProperty(options, 'second', {value: 'numeric',
- writable: true,
- enumerable: true,
- configurable: true});
+ %object_define_property(options, 'hour', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'minute', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ %object_define_property(options, 'second', {value: 'numeric',
+ writable: true,
+ enumerable: true,
+ configurable: true});
}
return options;
@@ -1592,7 +1602,7 @@
getOption, internalOptions);
var requestedLocale = locale.locale + extension;
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
calendar: {writable: true},
day: {writable: true},
era: {writable: true},
@@ -1603,7 +1613,6 @@
month: {writable: true},
numberingSystem: {writable: true},
[patternSymbol]: {writable: true},
- pattern: patternAccessor,
requestedLocale: {value: requestedLocale, writable: true},
second: {writable: true},
timeZone: {writable: true},
@@ -1622,7 +1631,10 @@
%MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
dateFormat[resolvedSymbol] = resolved;
- ObjectDefineProperty(dateFormat, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(resolved, 'pattern', patternAccessor);
+ %object_define_property(dateFormat, 'resolved', resolvedAccessor);
+ }
return dateFormat;
}
@@ -1756,15 +1768,14 @@
* DateTimeFormat.
* Returns undefined if date string cannot be parsed.
*/
-function parseDate(formatter, value) {
+function IntlParseDate(formatter, value) {
return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
GlobalString(value));
}
// 0 because date is optional argument.
-AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
-AddBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
+AddBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0, 'dateformat');
/**
@@ -1826,7 +1837,7 @@
'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
var locale = resolveLocale('breakiterator', locales, options);
- var resolved = ObjectDefineProperties({}, {
+ var resolved = %object_define_properties({}, {
requestedLocale: {value: locale.locale, writable: true},
type: {value: internalOptions.type, writable: true},
locale: {writable: true}
@@ -1839,7 +1850,9 @@
%MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator',
internalIterator);
iterator[resolvedSymbol] = resolved;
- ObjectDefineProperty(iterator, 'resolved', resolvedAccessor);
+ if (FLAG_intl_extra) {
+ %object_define_property(iterator, 'resolved', resolvedAccessor);
+ }
return iterator;
}
@@ -1950,11 +1963,13 @@
}
-AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1);
-AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0);
-AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0);
+AddBoundMethod(Intl.v8BreakIterator, 'adoptText', adoptText, 1,
+ 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'first', first, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'next', next, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'current', current, 0, 'breakiterator');
+AddBoundMethod(Intl.v8BreakIterator, 'breakType', breakType, 0,
+ 'breakiterator');
// Save references to Intl objects and methods we use, for added security.
var savedObjects = {
@@ -1992,6 +2007,37 @@
return new savedObjects[service](locales, useOptions);
}
+function LocaleConvertCase(s, locales, isToUpper) {
+ // ECMA 402 section 13.1.2 steps 1 through 12.
+ var language;
+ // Optimize for the most common two cases. initializeLocaleList() can handle
+ // them as well, but it's rather slow accounting for over 60% of
+ // toLocale{U,L}Case() and about 40% of toLocale{U,L}Case("<locale>").
+ if (IS_UNDEFINED(locales)) {
+ language = GetDefaultICULocaleJS();
+ } else if (IS_STRING(locales)) {
+ language = canonicalizeLanguageTag(locales);
+ } else {
+ var locales = initializeLocaleList(locales);
+ language = locales.length > 0 ? locales[0] : GetDefaultICULocaleJS();
+ }
+
+ // StringSplit is slower than this.
+ var pos = %_Call(StringIndexOf, language, '-');
+ if (pos != -1) {
+ language = %_Call(StringSubstring, language, 0, pos);
+ }
+
+ var CUSTOM_CASE_LANGUAGES = ['az', 'el', 'lt', 'tr'];
+ var langIndex = %_Call(ArrayIndexOf, CUSTOM_CASE_LANGUAGES, language);
+ if (langIndex == -1) {
+ // language-independent case conversion.
+ return isToUpper ? %StringToUpperCaseI18N(s) : %StringToLowerCaseI18N(s);
+ }
+ return %StringLocaleConvertCase(s, isToUpper,
+ CUSTOM_CASE_LANGUAGES[langIndex]);
+}
+
/**
* Compares this and that, and returns less than 0, 0 or greater than 0 value.
* Overrides the built-in method.
@@ -2044,6 +2090,56 @@
}
);
+function ToLowerCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
+ var s = TO_STRING(this);
+ return %StringToLowerCaseI18N(s);
+}
+
+function ToUpperCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toUpperCase");
+ var s = TO_STRING(this);
+ return %StringToUpperCaseI18N(s);
+}
+
+function ToLocaleLowerCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleLowerCase");
+ return LocaleConvertCase(TO_STRING(this), locales, false);
+}
+
+%FunctionSetLength(ToLocaleLowerCaseI18N, 0);
+
+function ToLocaleUpperCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleUpperCase");
+ return LocaleConvertCase(TO_STRING(this), locales, true);
+}
+
+%FunctionSetLength(ToLocaleUpperCaseI18N, 0);
+
+%FunctionRemovePrototype(ToLowerCaseI18N);
+%FunctionRemovePrototype(ToUpperCaseI18N);
+%FunctionRemovePrototype(ToLocaleLowerCaseI18N);
+%FunctionRemovePrototype(ToLocaleUpperCaseI18N);
+
+utils.Export(function(to) {
+ to.ToLowerCaseI18N = ToLowerCaseI18N;
+ to.ToUpperCaseI18N = ToUpperCaseI18N;
+ to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
+ to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
+});
+
/**
* Formats a Number object (this) using locale and options values.
@@ -2138,4 +2234,10 @@
}
);
+utils.Export(function(to) {
+ to.AddBoundMethod = AddBoundMethod;
+ to.IntlParseDate = IntlParseDate;
+ to.IntlParseNumber = IntlParseNumber;
+});
+
})
diff --git a/src/js/icu-case-mapping.js b/src/js/icu-case-mapping.js
new file mode 100644
index 0000000..9806249
--- /dev/null
+++ b/src/js/icu-case-mapping.js
@@ -0,0 +1,24 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalString = global.String;
+var OverrideFunction = utils.OverrideFunction;
+var ToLowerCaseI18N = utils.ImportNow("ToLowerCaseI18N");
+var ToUpperCaseI18N = utils.ImportNow("ToUpperCaseI18N");
+var ToLocaleLowerCaseI18N = utils.ImportNow("ToLocaleLowerCaseI18N");
+var ToLocaleUpperCaseI18N = utils.ImportNow("ToLocaleUpperCaseI18N");
+
+OverrideFunction(GlobalString.prototype, 'toLowerCase', ToLowerCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toUpperCase', ToUpperCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toLocaleLowerCase',
+ ToLocaleLowerCaseI18N, true);
+OverrideFunction(GlobalString.prototype, 'toLocaleUpperCase',
+ ToLocaleUpperCaseI18N, true);
+
+})
diff --git a/src/js/intl-extra.js b/src/js/intl-extra.js
new file mode 100644
index 0000000..a4d2256
--- /dev/null
+++ b/src/js/intl-extra.js
@@ -0,0 +1,22 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+var GlobalIntl = global.Intl;
+
+var AddBoundMethod = utils.ImportNow("AddBoundMethod");
+var IntlParseDate = utils.ImportNow("IntlParseDate");
+var IntlParseNumber = utils.ImportNow("IntlParseNumber");
+
+AddBoundMethod(GlobalIntl.DateTimeFormat, 'v8Parse', IntlParseDate, 1,
+ 'dateformat');
+AddBoundMethod(GlobalIntl.NumberFormat, 'v8Parse', IntlParseNumber, 1,
+ 'numberformat');
+
+})
diff --git a/src/js/macros.py b/src/js/macros.py
index a4c7f53..3cc2d6c 100644
--- a/src/js/macros.py
+++ b/src/js/macros.py
@@ -113,6 +113,7 @@
macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(arg));
macro TO_INT32(arg) = ((arg) | 0);
macro TO_UINT32(arg) = ((arg) >>> 0);
+macro INVERT_NEG_ZERO(arg) = ((arg) + 0);
macro TO_LENGTH(arg) = (%_ToLength(arg));
macro TO_STRING(arg) = (%_ToString(arg));
macro TO_NUMBER(arg) = (%_ToNumber(arg));
@@ -174,16 +175,6 @@
# 1-based so index of 1 returns the first capture
macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]);
-# PropertyDescriptor return value indices - must match
-# PropertyDescriptorIndices in runtime-object.cc.
-define IS_ACCESSOR_INDEX = 0;
-define VALUE_INDEX = 1;
-define GETTER_INDEX = 2;
-define SETTER_INDEX = 3;
-define WRITABLE_INDEX = 4;
-define ENUMERABLE_INDEX = 5;
-define CONFIGURABLE_INDEX = 6;
-
# For messages.js
# Matches Script::Type from objects.h
define TYPE_NATIVE = 0;
@@ -238,7 +229,6 @@
# Check whether debug is active.
define DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
-macro DEBUG_PREPARE_STEP_IN_IF_STEPPING(function) = if (%_DebugIsActive() != 0) %DebugPrepareStepInIfStepping(function);
# SharedFlag equivalents
define kNotShared = false;
@@ -251,7 +241,6 @@
define kMarkDequeOverflow = 3;
define kStoreBufferOverflow = 4;
define kSlotsBufferOverflow = 5;
-define kObjectObserve = 6;
define kForcedGC = 7;
define kSloppyMode = 8;
define kStrictMode = 9;
diff --git a/src/js/messages.js b/src/js/messages.js
index f8cb967..b5c4b56 100644
--- a/src/js/messages.js
+++ b/src/js/messages.js
@@ -23,6 +23,10 @@
utils.ImportNow("call_site_position_symbol");
var callSiteStrictSymbol =
utils.ImportNow("call_site_strict_symbol");
+var callSiteWasmObjectSymbol =
+ utils.ImportNow("call_site_wasm_obj_symbol");
+var callSiteWasmFunctionIndexSymbol =
+ utils.ImportNow("call_site_wasm_func_index_symbol");
var Float32x4ToString;
var formattedStackTraceSymbol =
utils.ImportNow("formatted_stack_trace_symbol");
@@ -32,12 +36,10 @@
var Int8x16ToString;
var InternalArray = utils.InternalArray;
var internalErrorSymbol = utils.ImportNow("internal_error_symbol");
-var ObjectDefineProperty;
var ObjectHasOwnProperty;
var ObjectToString = utils.ImportNow("object_to_string");
var Script = utils.ImportNow("Script");
var stackTraceSymbol = utils.ImportNow("stack_trace_symbol");
-var StringCharAt;
var StringIndexOf;
var StringSubstring;
var SymbolToString;
@@ -55,9 +57,7 @@
Int16x8ToString = from.Int16x8ToString;
Int32x4ToString = from.Int32x4ToString;
Int8x16ToString = from.Int8x16ToString;
- ObjectDefineProperty = from.ObjectDefineProperty;
ObjectHasOwnProperty = from.ObjectHasOwnProperty;
- StringCharAt = from.StringCharAt;
StringIndexOf = from.StringIndexOf;
StringSubstring = from.StringSubstring;
SymbolToString = from.SymbolToString;
@@ -255,6 +255,7 @@
return -1;
}
+
/**
* Get information on a specific source position.
* @param {number} position The source position
@@ -272,7 +273,7 @@
var line_ends = this.line_ends;
var start = line == 0 ? 0 : line_ends[line - 1] + 1;
var end = line_ends[line];
- if (end > 0 && %_Call(StringCharAt, this.source, end - 1) == '\r') {
+ if (end > 0 && %_StringCharAt(this.source, end - 1) === '\r') {
end--;
}
var column = position - start;
@@ -556,7 +557,9 @@
// Error implementation
function CallSite(receiver, fun, pos, strict_mode) {
- if (!IS_FUNCTION(fun)) {
+ // For wasm frames, receiver is the wasm object and fun is the function index
+ // instead of an actual function.
+ if (!IS_FUNCTION(fun) && !IS_NUMBER(fun)) {
throw MakeTypeError(kCallSiteExpectsFunction, typeof fun);
}
@@ -564,14 +567,19 @@
return new CallSite(receiver, fun, pos, strict_mode);
}
- SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
- SET_PRIVATE(this, callSiteFunctionSymbol, fun);
+ if (IS_FUNCTION(fun)) {
+ SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
+ SET_PRIVATE(this, callSiteFunctionSymbol, fun);
+ } else {
+ SET_PRIVATE(this, callSiteWasmObjectSymbol, receiver);
+ SET_PRIVATE(this, callSiteWasmFunctionIndexSymbol, TO_UINT32(fun));
+ }
SET_PRIVATE(this, callSitePositionSymbol, TO_INT32(pos));
SET_PRIVATE(this, callSiteStrictSymbol, TO_BOOLEAN(strict_mode));
}
function CheckCallSite(obj, name) {
- if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSiteFunctionSymbol)) {
+ if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSitePositionSymbol)) {
throw MakeTypeError(kCallSiteMethod, name);
}
}
@@ -622,6 +630,12 @@
function CallSiteGetFunctionName() {
// See if the function knows its own name
CheckCallSite(this, "getFunctionName");
+ if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+ var wasm = GET_PRIVATE(this, callSiteWasmObjectSymbol);
+ var func_index = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+ if (IS_UNDEFINED(wasm)) return "<WASM>";
+ return %WasmGetFunctionName(wasm, func_index);
+ }
return %CallSiteGetFunctionNameRT(this);
}
@@ -638,6 +652,9 @@
}
function CallSiteGetLineNumber() {
+ if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+ return GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+ }
CheckCallSite(this, "getLineNumber");
return %CallSiteGetLineNumberRT(this);
}
@@ -658,6 +675,13 @@
}
function CallSiteToString() {
+ if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
+ var funName = this.getFunctionName();
+ var funcIndex = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
+ var pos = this.getPosition();
+ return funName + " (<WASM>:" + funcIndex + ":" + pos + ")";
+ }
+
var fileName;
var fileLocation = "";
if (this.isNative()) {
@@ -795,14 +819,19 @@
function GetStackFrames(raw_stack) {
+ var internal_raw_stack = new InternalArray();
+ %MoveArrayContents(raw_stack, internal_raw_stack);
var frames = new InternalArray();
- var sloppy_frames = raw_stack[0];
- for (var i = 1; i < raw_stack.length; i += 4) {
- var recv = raw_stack[i];
- var fun = raw_stack[i + 1];
- var code = raw_stack[i + 2];
- var pc = raw_stack[i + 3];
- var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
+ var sloppy_frames = internal_raw_stack[0];
+ for (var i = 1; i < internal_raw_stack.length; i += 4) {
+ var recv = internal_raw_stack[i];
+ var fun = internal_raw_stack[i + 1];
+ var code = internal_raw_stack[i + 2];
+ var pc = internal_raw_stack[i + 3];
+ // For traps in wasm, the bytecode offset is passed as (-1 - offset).
+ // Otherwise, lookup the position from the pc.
+ var pos = IS_NUMBER(fun) && pc < 0 ? (-1 - pc) :
+ %FunctionGetPositionForOffset(code, pc);
sloppy_frames--;
frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
}
@@ -879,7 +908,7 @@
if (IS_UNDEFINED(stack_trace)) {
// Neither formatted nor structured stack trace available.
// Look further up the prototype chain.
- holder = %_GetPrototype(holder);
+ holder = %object_get_prototype_of(holder);
continue;
}
formatted_stack_trace = FormatStackTrace(holder, stack_trace);
@@ -995,9 +1024,9 @@
// Define actual captureStackTrace function after everything has been set up.
captureStackTrace = function captureStackTrace(obj, cons_opt) {
// Define accessors first, as this may fail and throw.
- ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
- set: StackTraceSetter,
- configurable: true });
+ %object_define_property(obj, 'stack', { get: StackTraceGetter,
+ set: StackTraceSetter,
+ configurable: true });
%CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
};
diff --git a/src/js/object-observe.js b/src/js/object-observe.js
deleted file mode 100644
index 5e256bf..0000000
--- a/src/js/object-observe.js
+++ /dev/null
@@ -1,717 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function(global, utils) {
-
-"use strict";
-
-%CheckIsBootstrapping();
-
-// -------------------------------------------------------------------
-// Imports
-
-var GetHash;
-var GlobalArray = global.Array;
-var GlobalObject = global.Object;
-var InternalArray = utils.InternalArray;
-var MakeTypeError;
-
-utils.Import(function(from) {
- GetHash = from.GetHash;
- MakeTypeError = from.MakeTypeError;
-});
-
-// -------------------------------------------------------------------
-
-// Overview:
-//
-// This file contains all of the routing and accounting for Object.observe.
-// User code will interact with these mechanisms via the Object.observe APIs
-// and, as a side effect of mutation objects which are observed. The V8 runtime
-// (both C++ and JS) will interact with these mechanisms primarily by enqueuing
-// proper change records for objects which were mutated. The Object.observe
-// routing and accounting consists primarily of three participants
-//
-// 1) ObjectInfo. This represents the observed state of a given object. It
-// records what callbacks are observing the object, with what options, and
-// what "change types" are in progress on the object (i.e. via
-// notifier.performChange).
-//
-// 2) CallbackInfo. This represents a callback used for observation. It holds
-// the records which must be delivered to the callback, as well as the global
-// priority of the callback (which determines delivery order between
-// callbacks).
-//
-// 3) observationState.pendingObservers. This is the set of observers which
-// have change records which must be delivered. During "normal" delivery
-// (i.e. not Object.deliverChangeRecords), this is the mechanism by which
-// callbacks are invoked in the proper order until there are no more
-// change records pending to a callback.
-//
-// Note that in order to reduce allocation and processing costs, the
-// implementation of (1) and (2) have "optimized" states which represent
-// common cases which can be handled more efficiently.
-
-var observationState;
-
-var notifierPrototype = {};
-
-// We have to wait until after bootstrapping to grab a reference to the
-// observationState object, since it's not possible to serialize that
-// reference into the snapshot.
-function GetObservationStateJS() {
- if (IS_UNDEFINED(observationState)) {
- observationState = %GetObservationState();
- }
-
- // TODO(adamk): Consider moving this code into heap.cc
- if (IS_UNDEFINED(observationState.callbackInfoMap)) {
- observationState.callbackInfoMap = %ObservationWeakMapCreate();
- observationState.objectInfoMap = %ObservationWeakMapCreate();
- observationState.notifierObjectInfoMap = %ObservationWeakMapCreate();
- observationState.pendingObservers = null;
- observationState.nextCallbackPriority = 0;
- observationState.lastMicrotaskId = 0;
- }
-
- return observationState;
-}
-
-
-function GetPendingObservers() {
- return GetObservationStateJS().pendingObservers;
-}
-
-
-function SetPendingObservers(pendingObservers) {
- GetObservationStateJS().pendingObservers = pendingObservers;
-}
-
-
-function GetNextCallbackPriority() {
- return GetObservationStateJS().nextCallbackPriority++;
-}
-
-
-function nullProtoObject() {
- return { __proto__: null };
-}
-
-
-function TypeMapCreate() {
- return nullProtoObject();
-}
-
-
-function TypeMapAddType(typeMap, type, ignoreDuplicate) {
- typeMap[type] = ignoreDuplicate ? 1 : (typeMap[type] || 0) + 1;
-}
-
-
-function TypeMapRemoveType(typeMap, type) {
- typeMap[type]--;
-}
-
-
-function TypeMapCreateFromList(typeList, length) {
- var typeMap = TypeMapCreate();
- for (var i = 0; i < length; i++) {
- TypeMapAddType(typeMap, typeList[i], true);
- }
- return typeMap;
-}
-
-
-function TypeMapHasType(typeMap, type) {
- return !!typeMap[type];
-}
-
-
-function TypeMapIsDisjointFrom(typeMap1, typeMap2) {
- if (!typeMap1 || !typeMap2)
- return true;
-
- for (var type in typeMap1) {
- if (TypeMapHasType(typeMap1, type) && TypeMapHasType(typeMap2, type))
- return false;
- }
-
- return true;
-}
-
-
-var defaultAcceptTypes = (function() {
- var defaultTypes = [
- 'add',
- 'update',
- 'delete',
- 'setPrototype',
- 'reconfigure',
- 'preventExtensions'
- ];
- return TypeMapCreateFromList(defaultTypes, defaultTypes.length);
-})();
-
-
-// An Observer is a registration to observe an object by a callback with
-// a given set of accept types. If the set of accept types is the default
-// set for Object.observe, the observer is represented as a direct reference
-// to the callback. An observer never changes its accept types and thus never
-// needs to "normalize".
-function ObserverCreate(callback, acceptList) {
- if (IS_UNDEFINED(acceptList))
- return callback;
- var observer = nullProtoObject();
- observer.callback = callback;
- observer.accept = acceptList;
- return observer;
-}
-
-
-function ObserverGetCallback(observer) {
- return IS_CALLABLE(observer) ? observer : observer.callback;
-}
-
-
-function ObserverGetAcceptTypes(observer) {
- return IS_CALLABLE(observer) ? defaultAcceptTypes : observer.accept;
-}
-
-
-function ObserverIsActive(observer, objectInfo) {
- return TypeMapIsDisjointFrom(ObjectInfoGetPerformingTypes(objectInfo),
- ObserverGetAcceptTypes(observer));
-}
-
-
-function ObjectInfoGetOrCreate(object) {
- var objectInfo = ObjectInfoGet(object);
- if (IS_UNDEFINED(objectInfo)) {
- if (!IS_PROXY(object)) {
- %SetIsObserved(object);
- }
- objectInfo = {
- object: object,
- changeObservers: null,
- notifier: null,
- performing: null,
- performingCount: 0,
- };
- %WeakCollectionSet(GetObservationStateJS().objectInfoMap,
- object, objectInfo, GetHash(object));
- }
- return objectInfo;
-}
-
-
-function ObjectInfoGet(object) {
- return %WeakCollectionGet(GetObservationStateJS().objectInfoMap, object,
- GetHash(object));
-}
-
-
-function ObjectInfoGetFromNotifier(notifier) {
- return %WeakCollectionGet(GetObservationStateJS().notifierObjectInfoMap,
- notifier, GetHash(notifier));
-}
-
-
-function ObjectInfoGetNotifier(objectInfo) {
- if (IS_NULL(objectInfo.notifier)) {
- var notifier = { __proto__: notifierPrototype };
- objectInfo.notifier = notifier;
- %WeakCollectionSet(GetObservationStateJS().notifierObjectInfoMap,
- notifier, objectInfo, GetHash(notifier));
- }
-
- return objectInfo.notifier;
-}
-
-
-function ChangeObserversIsOptimized(changeObservers) {
- return IS_CALLABLE(changeObservers) ||
- IS_CALLABLE(changeObservers.callback);
-}
-
-
-// The set of observers on an object is called 'changeObservers'. The first
-// observer is referenced directly via objectInfo.changeObservers. When a second
-// is added, changeObservers "normalizes" to become a mapping of callback
-// priority -> observer and is then stored on objectInfo.changeObservers.
-function ObjectInfoNormalizeChangeObservers(objectInfo) {
- if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
- var observer = objectInfo.changeObservers;
- var callback = ObserverGetCallback(observer);
- var callbackInfo = CallbackInfoGet(callback);
- var priority = CallbackInfoGetPriority(callbackInfo);
- objectInfo.changeObservers = nullProtoObject();
- objectInfo.changeObservers[priority] = observer;
- }
-}
-
-
-function ObjectInfoAddObserver(objectInfo, callback, acceptList) {
- var callbackInfo = CallbackInfoGetOrCreate(callback);
- var observer = ObserverCreate(callback, acceptList);
-
- if (!objectInfo.changeObservers) {
- objectInfo.changeObservers = observer;
- return;
- }
-
- ObjectInfoNormalizeChangeObservers(objectInfo);
- var priority = CallbackInfoGetPriority(callbackInfo);
- objectInfo.changeObservers[priority] = observer;
-}
-
-function ObjectInfoRemoveObserver(objectInfo, callback) {
- if (!objectInfo.changeObservers)
- return;
-
- if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
- if (callback === ObserverGetCallback(objectInfo.changeObservers))
- objectInfo.changeObservers = null;
- return;
- }
-
- var callbackInfo = CallbackInfoGet(callback);
- var priority = CallbackInfoGetPriority(callbackInfo);
- objectInfo.changeObservers[priority] = null;
-}
-
-function ObjectInfoHasActiveObservers(objectInfo) {
- if (IS_UNDEFINED(objectInfo) || !objectInfo.changeObservers)
- return false;
-
- if (ChangeObserversIsOptimized(objectInfo.changeObservers))
- return ObserverIsActive(objectInfo.changeObservers, objectInfo);
-
- for (var priority in objectInfo.changeObservers) {
- var observer = objectInfo.changeObservers[priority];
- if (!IS_NULL(observer) && ObserverIsActive(observer, objectInfo))
- return true;
- }
-
- return false;
-}
-
-
-function ObjectInfoAddPerformingType(objectInfo, type) {
- objectInfo.performing = objectInfo.performing || TypeMapCreate();
- TypeMapAddType(objectInfo.performing, type);
- objectInfo.performingCount++;
-}
-
-
-function ObjectInfoRemovePerformingType(objectInfo, type) {
- objectInfo.performingCount--;
- TypeMapRemoveType(objectInfo.performing, type);
-}
-
-
-function ObjectInfoGetPerformingTypes(objectInfo) {
- return objectInfo.performingCount > 0 ? objectInfo.performing : null;
-}
-
-
-function ConvertAcceptListToTypeMap(arg) {
- // We use undefined as a sentinel for the default accept list.
- if (IS_UNDEFINED(arg))
- return arg;
-
- if (!IS_RECEIVER(arg)) throw MakeTypeError(kObserveInvalidAccept);
-
- var len = TO_INTEGER(arg.length);
- if (len < 0) len = 0;
-
- return TypeMapCreateFromList(arg, len);
-}
-
-
-// CallbackInfo's optimized state is just a number which represents its global
-// priority. When a change record must be enqueued for the callback, it
-// normalizes. When delivery clears any pending change records, it re-optimizes.
-function CallbackInfoGet(callback) {
- return %WeakCollectionGet(GetObservationStateJS().callbackInfoMap, callback,
- GetHash(callback));
-}
-
-
-function CallbackInfoSet(callback, callbackInfo) {
- %WeakCollectionSet(GetObservationStateJS().callbackInfoMap,
- callback, callbackInfo, GetHash(callback));
-}
-
-
-function CallbackInfoGetOrCreate(callback) {
- var callbackInfo = CallbackInfoGet(callback);
- if (!IS_UNDEFINED(callbackInfo))
- return callbackInfo;
-
- var priority = GetNextCallbackPriority();
- CallbackInfoSet(callback, priority);
- return priority;
-}
-
-
-function CallbackInfoGetPriority(callbackInfo) {
- if (IS_NUMBER(callbackInfo))
- return callbackInfo;
- else
- return callbackInfo.priority;
-}
-
-
-function CallbackInfoNormalize(callback) {
- var callbackInfo = CallbackInfoGet(callback);
- if (IS_NUMBER(callbackInfo)) {
- var priority = callbackInfo;
- callbackInfo = new InternalArray;
- callbackInfo.priority = priority;
- CallbackInfoSet(callback, callbackInfo);
- }
- return callbackInfo;
-}
-
-
-function ObjectObserve(object, callback, acceptList) {
- if (!IS_RECEIVER(object))
- throw MakeTypeError(kObserveNonObject, "observe", "observe");
- if (%IsJSGlobalProxy(object))
- throw MakeTypeError(kObserveGlobalProxy, "observe");
- if (%IsAccessCheckNeeded(object))
- throw MakeTypeError(kObserveAccessChecked, "observe");
- if (!IS_CALLABLE(callback))
- throw MakeTypeError(kObserveNonFunction, "observe");
- if (%object_is_frozen(callback))
- throw MakeTypeError(kObserveCallbackFrozen);
-
- var objectObserveFn = %GetObjectContextObjectObserve(object);
- return objectObserveFn(object, callback, acceptList);
-}
-
-
-function NativeObjectObserve(object, callback, acceptList) {
- var objectInfo = ObjectInfoGetOrCreate(object);
- var typeList = ConvertAcceptListToTypeMap(acceptList);
- ObjectInfoAddObserver(objectInfo, callback, typeList);
- return object;
-}
-
-
-function ObjectUnobserve(object, callback) {
- if (!IS_RECEIVER(object))
- throw MakeTypeError(kObserveNonObject, "unobserve", "unobserve");
- if (%IsJSGlobalProxy(object))
- throw MakeTypeError(kObserveGlobalProxy, "unobserve");
- if (!IS_CALLABLE(callback))
- throw MakeTypeError(kObserveNonFunction, "unobserve");
-
- var objectInfo = ObjectInfoGet(object);
- if (IS_UNDEFINED(objectInfo))
- return object;
-
- ObjectInfoRemoveObserver(objectInfo, callback);
- return object;
-}
-
-
-function ArrayObserve(object, callback) {
- return ObjectObserve(object, callback, ['add',
- 'update',
- 'delete',
- 'splice']);
-}
-
-
-function ArrayUnobserve(object, callback) {
- return ObjectUnobserve(object, callback);
-}
-
-
-function ObserverEnqueueIfActive(observer, objectInfo, changeRecord) {
- if (!ObserverIsActive(observer, objectInfo) ||
- !TypeMapHasType(ObserverGetAcceptTypes(observer), changeRecord.type)) {
- return;
- }
-
- var callback = ObserverGetCallback(observer);
- if (!%ObserverObjectAndRecordHaveSameOrigin(callback, changeRecord.object,
- changeRecord)) {
- return;
- }
-
- var callbackInfo = CallbackInfoNormalize(callback);
- if (IS_NULL(GetPendingObservers())) {
- SetPendingObservers(nullProtoObject());
- if (DEBUG_IS_ACTIVE) {
- var id = ++GetObservationStateJS().lastMicrotaskId;
- var name = "Object.observe";
- %EnqueueMicrotask(function() {
- %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
- ObserveMicrotaskRunner();
- %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
- });
- %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
- } else {
- %EnqueueMicrotask(ObserveMicrotaskRunner);
- }
- }
- GetPendingObservers()[callbackInfo.priority] = callback;
- callbackInfo.push(changeRecord);
-}
-
-
-function ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, type) {
- if (!ObjectInfoHasActiveObservers(objectInfo))
- return;
-
- var hasType = !IS_UNDEFINED(type);
- var newRecord = hasType ?
- { object: objectInfo.object, type: type } :
- { object: objectInfo.object };
-
- for (var prop in changeRecord) {
- if (prop === 'object' || (hasType && prop === 'type')) continue;
- %DefineDataPropertyUnchecked(
- newRecord, prop, changeRecord[prop], READ_ONLY + DONT_DELETE);
- }
- %object_freeze(newRecord);
-
- ObjectInfoEnqueueInternalChangeRecord(objectInfo, newRecord);
-}
-
-
-function ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(changeRecord.name)) return;
-
- if (ChangeObserversIsOptimized(objectInfo.changeObservers)) {
- var observer = objectInfo.changeObservers;
- ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
- return;
- }
-
- for (var priority in objectInfo.changeObservers) {
- var observer = objectInfo.changeObservers[priority];
- if (IS_NULL(observer))
- continue;
- ObserverEnqueueIfActive(observer, objectInfo, changeRecord);
- }
-}
-
-
-function BeginPerformSplice(array) {
- var objectInfo = ObjectInfoGet(array);
- if (!IS_UNDEFINED(objectInfo))
- ObjectInfoAddPerformingType(objectInfo, 'splice');
-}
-
-
-function EndPerformSplice(array) {
- var objectInfo = ObjectInfoGet(array);
- if (!IS_UNDEFINED(objectInfo))
- ObjectInfoRemovePerformingType(objectInfo, 'splice');
-}
-
-
-function EnqueueSpliceRecord(array, index, removed, addedCount) {
- var objectInfo = ObjectInfoGet(array);
- if (!ObjectInfoHasActiveObservers(objectInfo))
- return;
-
- var changeRecord = {
- type: 'splice',
- object: array,
- index: index,
- removed: removed,
- addedCount: addedCount
- };
-
- %object_freeze(changeRecord);
- %object_freeze(changeRecord.removed);
- ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function NotifyChange(type, object, name, oldValue) {
- var objectInfo = ObjectInfoGet(object);
- if (!ObjectInfoHasActiveObservers(objectInfo))
- return;
-
- var changeRecord;
- if (arguments.length == 2) {
- changeRecord = { type: type, object: object };
- } else if (arguments.length == 3) {
- changeRecord = { type: type, object: object, name: name };
- } else {
- changeRecord = {
- type: type,
- object: object,
- name: name,
- oldValue: oldValue
- };
- }
-
- %object_freeze(changeRecord);
- ObjectInfoEnqueueInternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function ObjectNotifierNotify(changeRecord) {
- if (!IS_RECEIVER(this))
- throw MakeTypeError(kCalledOnNonObject, "notify");
-
- var objectInfo = ObjectInfoGetFromNotifier(this);
- if (IS_UNDEFINED(objectInfo))
- throw MakeTypeError(kObserveNotifyNonNotifier);
- if (!IS_STRING(changeRecord.type))
- throw MakeTypeError(kObserveTypeNonString);
-
- ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord);
-}
-
-
-function ObjectNotifierPerformChange(changeType, changeFn) {
- if (!IS_RECEIVER(this))
- throw MakeTypeError(kCalledOnNonObject, "performChange");
-
- var objectInfo = ObjectInfoGetFromNotifier(this);
- if (IS_UNDEFINED(objectInfo))
- throw MakeTypeError(kObserveNotifyNonNotifier);
- if (!IS_STRING(changeType))
- throw MakeTypeError(kObservePerformNonString);
- if (!IS_CALLABLE(changeFn))
- throw MakeTypeError(kObservePerformNonFunction);
-
- var performChangeFn = %GetObjectContextNotifierPerformChange(objectInfo);
- performChangeFn(objectInfo, changeType, changeFn);
-}
-
-
-function NativeObjectNotifierPerformChange(objectInfo, changeType, changeFn) {
- ObjectInfoAddPerformingType(objectInfo, changeType);
-
- var changeRecord;
- try {
- changeRecord = changeFn();
- } finally {
- ObjectInfoRemovePerformingType(objectInfo, changeType);
- }
-
- if (IS_RECEIVER(changeRecord))
- ObjectInfoEnqueueExternalChangeRecord(objectInfo, changeRecord, changeType);
-}
-
-
-function ObjectGetNotifier(object) {
- if (!IS_RECEIVER(object))
- throw MakeTypeError(kObserveNonObject, "getNotifier", "getNotifier");
- if (%IsJSGlobalProxy(object))
- throw MakeTypeError(kObserveGlobalProxy, "getNotifier");
- if (%IsAccessCheckNeeded(object))
- throw MakeTypeError(kObserveAccessChecked, "getNotifier");
-
- if (%object_is_frozen(object)) return null;
-
- if (!%ObjectWasCreatedInCurrentOrigin(object)) return null;
-
- var getNotifierFn = %GetObjectContextObjectGetNotifier(object);
- return getNotifierFn(object);
-}
-
-
-function NativeObjectGetNotifier(object) {
- var objectInfo = ObjectInfoGetOrCreate(object);
- return ObjectInfoGetNotifier(objectInfo);
-}
-
-
-function CallbackDeliverPending(callback) {
- var callbackInfo = CallbackInfoGet(callback);
- if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
- return false;
-
- // Clear the pending change records from callback and return it to its
- // "optimized" state.
- var priority = callbackInfo.priority;
- CallbackInfoSet(callback, priority);
-
- var pendingObservers = GetPendingObservers();
- if (!IS_NULL(pendingObservers))
- delete pendingObservers[priority];
-
- // TODO: combine the following runtime calls for perf optimization.
- var delivered = [];
- %MoveArrayContents(callbackInfo, delivered);
- %DeliverObservationChangeRecords(callback, delivered);
-
- return true;
-}
-
-
-function ObjectDeliverChangeRecords(callback) {
- if (!IS_CALLABLE(callback))
- throw MakeTypeError(kObserveNonFunction, "deliverChangeRecords");
-
- while (CallbackDeliverPending(callback)) {}
-}
-
-
-function ObserveMicrotaskRunner() {
- var pendingObservers = GetPendingObservers();
- if (!IS_NULL(pendingObservers)) {
- SetPendingObservers(null);
- for (var i in pendingObservers) {
- CallbackDeliverPending(pendingObservers[i]);
- }
- }
-}
-
-// -------------------------------------------------------------------
-
-utils.InstallFunctions(notifierPrototype, DONT_ENUM, [
- "notify", ObjectNotifierNotify,
- "performChange", ObjectNotifierPerformChange
-]);
-
-var ObserveObjectMethods = [
- "deliverChangeRecords", ObjectDeliverChangeRecords,
- "getNotifier", ObjectGetNotifier,
- "observe", ObjectObserve,
- "unobserve", ObjectUnobserve
-];
-
-var ObserveArrayMethods = [
- "observe", ArrayObserve,
- "unobserve", ArrayUnobserve
-];
-
-// TODO(adamk): Figure out why this prototype removal has to
-// happen as part of initial snapshotting.
-var removePrototypeFn = function(f, i) {
- if (i % 2 === 1) %FunctionRemovePrototype(f);
-};
-ObserveObjectMethods.forEach(removePrototypeFn);
-ObserveArrayMethods.forEach(removePrototypeFn);
-
-%InstallToContext([
- "native_object_get_notifier", NativeObjectGetNotifier,
- "native_object_notifier_perform_change", NativeObjectNotifierPerformChange,
- "native_object_observe", NativeObjectObserve,
- "observers_begin_perform_splice", BeginPerformSplice,
- "observers_end_perform_splice", EndPerformSplice,
- "observers_enqueue_splice", EnqueueSpliceRecord,
- "observers_notify_change", NotifyChange,
-]);
-
-utils.Export(function(to) {
- to.ObserveArrayMethods = ObserveArrayMethods;
- to.ObserveBeginPerformSplice = BeginPerformSplice;
- to.ObserveEndPerformSplice = EndPerformSplice;
- to.ObserveEnqueueSpliceRecord = EnqueueSpliceRecord;
- to.ObserveObjectMethods = ObserveObjectMethods;
-});
-
-})
diff --git a/src/js/prologue.js b/src/js/prologue.js
index f9589a5..b352eb1 100644
--- a/src/js/prologue.js
+++ b/src/js/prologue.js
@@ -128,10 +128,10 @@
function OverrideFunction(object, name, f, afterInitialBootstrap) {
%CheckIsBootstrapping();
- %ObjectDefineProperty(object, name, { value: f,
- writeable: true,
- configurable: true,
- enumerable: false });
+ %object_define_property(object, name, { value: f,
+ writeable: true,
+ configurable: true,
+ enumerable: false });
SetFunctionName(f, name);
if (!afterInitialBootstrap) %FunctionRemovePrototype(f);
%SetNativeFlag(f);
@@ -181,10 +181,15 @@
// Whitelist of exports from normal natives to experimental natives and debug.
var expose_list = [
+ "AddBoundMethod",
"ArrayToString",
+ "AsyncFunctionNext",
+ "AsyncFunctionThrow",
"ErrorToString",
"GetIterator",
"GetMethod",
+ "IntlParseDate",
+ "IntlParseNumber",
"IsNaN",
"MakeError",
"MakeRangeError",
@@ -195,12 +200,12 @@
"MaxSimple",
"MinSimple",
"NumberIsInteger",
- "ObjectDefineProperty",
- "ObserveArrayMethods",
- "ObserveObjectMethods",
"PromiseChain",
- "PromiseDeferred",
- "PromiseResolved",
+ "PromiseDefer",
+ "PromiseAccept",
+ "PromiseCreateRejected",
+ "PromiseCreateResolved",
+ "PromiseThen",
"RegExpSubclassExecJS",
"RegExpSubclassMatch",
"RegExpSubclassReplace",
@@ -211,12 +216,16 @@
"SetIteratorNext",
"SetValues",
"SymbolToString",
+ "ToLocaleLowerCaseI18N",
+ "ToLocaleUpperCaseI18N",
+ "ToLowerCaseI18N",
"ToPositiveInteger",
+ "ToUpperCaseI18N",
// From runtime:
"is_concat_spreadable_symbol",
"iterator_symbol",
- "promise_status_symbol",
- "promise_value_symbol",
+ "promise_result_symbol",
+ "promise_state_symbol",
"object_freeze",
"object_is_frozen",
"object_is_sealed",
diff --git a/src/js/promise-extra.js b/src/js/promise-extra.js
index f6f7959..34d7323 100644
--- a/src/js/promise-extra.js
+++ b/src/js/promise-extra.js
@@ -11,16 +11,16 @@
var GlobalPromise = global.Promise;
var PromiseChain = utils.ImportNow("PromiseChain");
-var PromiseDeferred = utils.ImportNow("PromiseDeferred");
-var PromiseResolved = utils.ImportNow("PromiseResolved");
+var PromiseDefer = utils.ImportNow("PromiseDefer");
+var PromiseAccept = utils.ImportNow("PromiseAccept");
utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
"chain", PromiseChain,
]);
utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
- "defer", PromiseDeferred,
- "accept", PromiseResolved,
+ "defer", PromiseDefer,
+ "accept", PromiseAccept,
]);
})
diff --git a/src/js/promise.js b/src/js/promise.js
index bcf826a..42b772b 100644
--- a/src/js/promise.js
+++ b/src/js/promise.js
@@ -17,12 +17,13 @@
utils.ImportNow("promise_combined_deferred_symbol");
var promiseHasHandlerSymbol =
utils.ImportNow("promise_has_handler_symbol");
-var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol");
-var promiseOnResolveSymbol =
- utils.ImportNow("promise_on_resolve_symbol");
+var promiseRejectReactionsSymbol =
+ utils.ImportNow("promise_reject_reactions_symbol");
+var promiseFulfillReactionsSymbol =
+ utils.ImportNow("promise_fulfill_reactions_symbol");
var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
-var promiseStatusSymbol = utils.ImportNow("promise_status_symbol");
-var promiseValueSymbol = utils.ImportNow("promise_value_symbol");
+var promiseStateSymbol = utils.ImportNow("promise_state_symbol");
+var promiseResultSymbol = utils.ImportNow("promise_result_symbol");
var SpeciesConstructor;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
@@ -33,22 +34,32 @@
// -------------------------------------------------------------------
-// Status values: 0 = pending, +1 = resolved, -1 = rejected
+// [[PromiseState]] values:
+const kPending = 0;
+const kFulfilled = +1;
+const kRejected = -1;
+
var lastMicrotaskId = 0;
+// ES#sec-createresolvingfunctions
+// CreateResolvingFunctions ( promise )
function CreateResolvingFunctions(promise) {
var alreadyResolved = false;
+ // ES#sec-promise-resolve-functions
+ // Promise Resolve Functions
var resolve = value => {
if (alreadyResolved === true) return;
alreadyResolved = true;
- PromiseResolve(promise, value);
+ FulfillPromise(promise, value);
};
+ // ES#sec-promise-reject-functions
+ // Promise Reject Functions
var reject = reason => {
if (alreadyResolved === true) return;
alreadyResolved = true;
- PromiseReject(promise, reason);
+ RejectPromise(promise, reason);
};
return {
@@ -59,13 +70,16 @@
}
+// ES#sec-promise-executor
+// Promise ( executor )
var GlobalPromise = function Promise(resolver) {
if (resolver === promiseRawSymbol) {
return %_NewObject(GlobalPromise, new.target);
}
if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);
- if (!IS_CALLABLE(resolver))
+ if (!IS_CALLABLE(resolver)) {
throw MakeTypeError(kResolverNotAFunction, resolver);
+ }
var promise = PromiseInit(%_NewObject(GlobalPromise, new.target));
var callbacks = CreateResolvingFunctions(promise);
@@ -85,27 +99,27 @@
// Core functionality.
function PromiseSet(promise, status, value, onResolve, onReject) {
- SET_PRIVATE(promise, promiseStatusSymbol, status);
- SET_PRIVATE(promise, promiseValueSymbol, value);
- SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve);
- SET_PRIVATE(promise, promiseOnRejectSymbol, onReject);
+ SET_PRIVATE(promise, promiseStateSymbol, status);
+ SET_PRIVATE(promise, promiseResultSymbol, value);
+ SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);
+ SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);
return promise;
}
function PromiseCreateAndSet(status, value) {
var promise = new GlobalPromise(promiseRawSymbol);
// If debug is active, notify about the newly created promise first.
- if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
+ if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);
return PromiseSet(promise, status, value);
}
function PromiseInit(promise) {
return PromiseSet(
- promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+ promise, kPending, UNDEFINED, new InternalArray, new InternalArray)
}
function PromiseDone(promise, status, value, promiseQueue) {
- if (GET_PRIVATE(promise, promiseStatusSymbol) === 0) {
+ if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
var tasks = GET_PRIVATE(promise, promiseQueue);
if (tasks.length) PromiseEnqueue(value, tasks, status);
PromiseSet(promise, status, value);
@@ -139,7 +153,7 @@
});
if (instrumenting) {
id = ++lastMicrotaskId;
- name = status > 0 ? "Promise.resolve" : "Promise.reject";
+ name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
%DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
}
}
@@ -154,24 +168,27 @@
// For bootstrapper.
+// ES#sec-ispromise IsPromise ( x )
function IsPromise(x) {
- return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol);
+ return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol);
}
function PromiseCreate() {
return new GlobalPromise(PromiseNopResolver)
}
-function PromiseResolve(promise, x) {
+// ES#sec-fulfillpromise
+// FulfillPromise ( promise, value)
+function FulfillPromise(promise, x) {
if (x === promise) {
- return PromiseReject(promise, MakeTypeError(kPromiseCyclic, x));
+ return RejectPromise(promise, MakeTypeError(kPromiseCyclic, x));
}
if (IS_RECEIVER(x)) {
// 25.4.1.3.2 steps 8-12
try {
var then = x.then;
} catch (e) {
- return PromiseReject(promise, e);
+ return RejectPromise(promise, e);
}
if (IS_CALLABLE(then)) {
// PromiseResolveThenableJob
@@ -198,22 +215,26 @@
return;
}
}
- PromiseDone(promise, +1, x, promiseOnResolveSymbol);
+ PromiseDone(promise, kFulfilled, x, promiseFulfillReactionsSymbol);
}
-function PromiseReject(promise, r) {
+// ES#sec-rejectpromise
+// RejectPromise ( promise, reason )
+function RejectPromise(promise, r) {
// Check promise status to confirm that this reject has an effect.
// Call runtime for callbacks to the debugger or for unhandled reject.
- if (GET_PRIVATE(promise, promiseStatusSymbol) == 0) {
+ if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
var debug_is_active = DEBUG_IS_ACTIVE;
if (debug_is_active ||
!HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
%PromiseRejectEvent(promise, r, debug_is_active);
}
}
- PromiseDone(promise, -1, r, promiseOnRejectSymbol)
+ PromiseDone(promise, kRejected, r, promiseRejectReactionsSymbol)
}
+// ES#sec-newpromisecapability
+// NewPromiseCapability ( C )
function NewPromiseCapability(C) {
if (C === GlobalPromise) {
// Optimized case, avoid extra closure.
@@ -240,23 +261,27 @@
return result;
}
-function PromiseDeferred() {
+// Unspecified V8-specific legacy function
+function PromiseDefer() {
%IncrementUseCounter(kPromiseDefer);
return NewPromiseCapability(this);
}
-function PromiseResolved(x) {
+// Unspecified V8-specific legacy function
+function PromiseAccept(x) {
%IncrementUseCounter(kPromiseAccept);
- return %_Call(PromiseCast, this, x);
+ return %_Call(PromiseResolve, this, x);
}
-function PromiseRejected(r) {
+// ES#sec-promise.reject
+// Promise.reject ( x )
+function PromiseReject(r) {
if (!IS_RECEIVER(this)) {
- throw MakeTypeError(kCalledOnNonObject, PromiseRejected);
+ throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
}
if (this === GlobalPromise) {
// Optimized case, avoid extra closure.
- var promise = PromiseCreateAndSet(-1, r);
+ var promise = PromiseCreateAndSet(kRejected, r);
// The debug event for this would always be an uncaught promise reject,
// which is usually simply noise. Do not trigger that debug event.
%PromiseRejectEvent(promise, r, false);
@@ -268,10 +293,21 @@
}
}
-// Multi-unwrapped chaining with thenable coercion.
+// Shortcut Promise.reject and Promise.resolve() implementations, used by
+// Async Functions implementation.
+function PromiseCreateRejected(r) {
+ return %_Call(PromiseReject, GlobalPromise, r);
+}
+function PromiseCreateResolved(x) {
+ return %_Call(PromiseResolve, GlobalPromise, x);
+}
+
+// ES#sec-promise.prototype.then
+// Promise.prototype.then ( onFulfilled, onRejected )
+// Multi-unwrapped chaining with thenable coercion.
function PromiseThen(onResolve, onReject) {
- var status = GET_PRIVATE(this, promiseStatusSymbol);
+ var status = GET_PRIVATE(this, promiseStateSymbol);
if (IS_UNDEFINED(status)) {
throw MakeTypeError(kNotAPromise, this);
}
@@ -281,24 +317,25 @@
onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;
var deferred = NewPromiseCapability(constructor);
switch (status) {
- case 0: // Pending
- GET_PRIVATE(this, promiseOnResolveSymbol).push(onResolve, deferred);
- GET_PRIVATE(this, promiseOnRejectSymbol).push(onReject, deferred);
+ case kPending:
+ GET_PRIVATE(this, promiseFulfillReactionsSymbol).push(onResolve,
+ deferred);
+ GET_PRIVATE(this, promiseRejectReactionsSymbol).push(onReject, deferred);
break;
- case +1: // Resolved
- PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+ case kFulfilled:
+ PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
[onResolve, deferred],
- +1);
+ kFulfilled);
break;
- case -1: // Rejected
+ case kRejected:
if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
// Promise has already been rejected, but had no handler.
// Revoke previously triggered reject event.
%PromiseRevokeReject(this);
}
- PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol),
+ PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
[onReject, deferred],
- -1);
+ kRejected);
break;
}
// Mark this promise as having handler.
@@ -306,21 +343,26 @@
return deferred.promise;
}
+// Unspecified V8-specific legacy function
// Chain is left around for now as an alias for then
function PromiseChain(onResolve, onReject) {
%IncrementUseCounter(kPromiseChain);
return %_Call(PromiseThen, this, onResolve, onReject);
}
+// ES#sec-promise.prototype.catch
+// Promise.prototype.catch ( onRejected )
function PromiseCatch(onReject) {
return this.then(UNDEFINED, onReject);
}
// Combinators.
-function PromiseCast(x) {
+// ES#sec-promise.resolve
+// Promise.resolve ( x )
+function PromiseResolve(x) {
if (!IS_RECEIVER(this)) {
- throw MakeTypeError(kCalledOnNonObject, PromiseCast);
+ throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
}
if (IsPromise(x) && x.constructor === this) return x;
@@ -329,6 +371,8 @@
return promiseCapability.promise;
}
+// ES#sec-promise.all
+// Promise.all ( iterable )
function PromiseAll(iterable) {
if (!IS_RECEIVER(this)) {
throw MakeTypeError(kCalledOnNonObject, "Promise.all");
@@ -378,6 +422,8 @@
return deferred.promise;
}
+// ES#sec-promise.race
+// Promise.race ( iterable )
function PromiseRace(iterable) {
if (!IS_RECEIVER(this)) {
throw MakeTypeError(kCalledOnNonObject, PromiseRace);
@@ -399,7 +445,7 @@
// Utility for debugger
function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
- var queue = GET_PRIVATE(promise, promiseOnRejectSymbol);
+ var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
if (IS_UNDEFINED(queue)) return false;
for (var i = 0; i < queue.length; i += 2) {
var handler = queue[i];
@@ -432,10 +478,10 @@
DONT_ENUM | READ_ONLY);
utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
- "reject", PromiseRejected,
+ "reject", PromiseReject,
"all", PromiseAll,
"race", PromiseRace,
- "resolve", PromiseCast
+ "resolve", PromiseResolve
]);
utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
@@ -448,9 +494,11 @@
"promise_chain", PromiseChain,
"promise_create", PromiseCreate,
"promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
- "promise_reject", PromiseReject,
- "promise_resolve", PromiseResolve,
+ "promise_reject", RejectPromise,
+ "promise_resolve", FulfillPromise,
"promise_then", PromiseThen,
+ "promise_create_rejected", PromiseCreateRejected,
+ "promise_create_resolved", PromiseCreateResolved
]);
// This allows extras to create promises quickly without building extra
@@ -458,18 +506,22 @@
// promise without having to hold on to those closures forever.
utils.InstallFunctions(extrasUtils, 0, [
"createPromise", PromiseCreate,
- "resolvePromise", PromiseResolve,
- "rejectPromise", PromiseReject
+ "resolvePromise", FulfillPromise,
+ "rejectPromise", RejectPromise
]);
// TODO(v8:4567): Allow experimental natives to remove function prototype
-[PromiseChain, PromiseDeferred, PromiseResolved].forEach(
+[PromiseChain, PromiseDefer, PromiseAccept].forEach(
fn => %FunctionRemovePrototype(fn));
utils.Export(function(to) {
to.PromiseChain = PromiseChain;
- to.PromiseDeferred = PromiseDeferred;
- to.PromiseResolved = PromiseResolved;
+ to.PromiseDefer = PromiseDefer;
+ to.PromiseAccept = PromiseAccept;
+
+ to.PromiseCreateRejected = PromiseCreateRejected;
+ to.PromiseCreateResolved = PromiseCreateResolved;
+ to.PromiseThen = PromiseThen;
});
})
diff --git a/src/js/regexp.js b/src/js/regexp.js
index cc8cb41..719a081 100644
--- a/src/js/regexp.js
+++ b/src/js/regexp.js
@@ -4,14 +4,11 @@
(function(global, utils) {
-'use strict';
-
%CheckIsBootstrapping();
// -------------------------------------------------------------------
// Imports
-var AddIndexedProperty;
var ExpandReplacement;
var GlobalArray = global.Array;
var GlobalObject = global.Object;
@@ -29,7 +26,6 @@
var SpeciesConstructor;
utils.Import(function(from) {
- AddIndexedProperty = from.AddIndexedProperty;
ExpandReplacement = from.ExpandReplacement;
MakeTypeError = from.MakeTypeError;
MaxSimple = from.MaxSimple;
@@ -502,7 +498,7 @@
var result;
if (size === 0) {
result = RegExpSubclassExec(splitter, string);
- if (IS_NULL(result)) AddIndexedProperty(array, 0, string);
+ if (IS_NULL(result)) %AddElement(array, 0, string);
return array;
}
var stringIndex = prevStringIndex;
@@ -515,10 +511,10 @@
stringIndex += AdvanceStringIndex(string, stringIndex, unicode);
} else {
var end = MinSimple(TO_LENGTH(splitter.lastIndex), size);
- if (end === stringIndex) {
+ if (end === prevStringIndex) {
stringIndex += AdvanceStringIndex(string, stringIndex, unicode);
} else {
- AddIndexedProperty(
+ %AddElement(
array, arrayIndex,
%_SubString(string, prevStringIndex, stringIndex));
arrayIndex++;
@@ -526,7 +522,7 @@
prevStringIndex = end;
var numberOfCaptures = MaxSimple(TO_LENGTH(result.length), 0);
for (var i = 1; i < numberOfCaptures; i++) {
- AddIndexedProperty(array, arrayIndex, result[i]);
+ %AddElement(array, arrayIndex, result[i]);
arrayIndex++;
if (arrayIndex === lim) return array;
}
@@ -534,7 +530,7 @@
}
}
}
- AddIndexedProperty(array, arrayIndex,
+ %AddElement(array, arrayIndex,
%_SubString(string, prevStringIndex, size));
return array;
}
diff --git a/src/js/runtime.js b/src/js/runtime.js
index 8e4f283..a6a0b4d 100644
--- a/src/js/runtime.js
+++ b/src/js/runtime.js
@@ -43,19 +43,6 @@
*/
-// This function should be called rather than %AddElement in contexts where the
-// argument might not be less than 2**32-1. ES2015 ToLength semantics mean that
-// this is a concern at basically all callsites.
-function AddIndexedProperty(obj, index, value) {
- if (index === TO_UINT32(index) && index !== kMaxUint32) {
- %AddElement(obj, index, value);
- } else {
- %AddNamedProperty(obj, TO_STRING(index), value, NONE);
- }
-}
-%SetForceInlineFlag(AddIndexedProperty);
-
-
function ToPositiveInteger(x, rangeErrorIndex) {
var i = TO_INTEGER_MAP_MINUS_ZERO(x);
if (i < 0) throw MakeRangeError(rangeErrorIndex);
@@ -122,7 +109,6 @@
// Exports
utils.Export(function(to) {
- to.AddIndexedProperty = AddIndexedProperty;
to.MaxSimple = MaxSimple;
to.MinSimple = MinSimple;
to.ToPositiveInteger = ToPositiveInteger;
diff --git a/src/js/string.js b/src/js/string.js
index 0eb394e..badb2b4 100644
--- a/src/js/string.js
+++ b/src/js/string.js
@@ -57,30 +57,6 @@
}
-// ECMA-262, section 15.5.4.4
-function StringCharAtJS(pos) {
- CHECK_OBJECT_COERCIBLE(this, "String.prototype.charAt");
-
- var result = %_StringCharAt(this, pos);
- if (%_IsSmi(result)) {
- result = %_StringCharAt(TO_STRING(this), TO_INTEGER(pos));
- }
- return result;
-}
-
-
-// ECMA-262 section 15.5.4.5
-function StringCharCodeAtJS(pos) {
- CHECK_OBJECT_COERCIBLE(this, "String.prototype.charCodeAt");
-
- var result = %_StringCharCodeAt(this, pos);
- if (!%_IsSmi(result)) {
- result = %_StringCharCodeAt(TO_STRING(this), TO_INTEGER(pos));
- }
- return result;
-}
-
-
// ECMA-262, section 15.5.4.6
function StringConcat(other /* and more */) { // length == 1
"use strict";
@@ -845,13 +821,6 @@
// -------------------------------------------------------------------
-// Set the String function and constructor.
-%FunctionSetPrototype(GlobalString, new GlobalString());
-
-// Set up the constructor property on the String prototype object.
-%AddNamedProperty(
- GlobalString.prototype, "constructor", GlobalString, DONT_ENUM);
-
// Set up the non-enumerable functions on the String object.
utils.InstallFunctions(GlobalString, DONT_ENUM, [
"fromCodePoint", StringFromCodePoint,
@@ -862,8 +831,6 @@
utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
"valueOf", StringValueOf,
"toString", StringToString,
- "charAt", StringCharAtJS,
- "charCodeAt", StringCharCodeAtJS,
"codePointAt", StringCodePointAt,
"concat", StringConcat,
"endsWith", StringEndsWith,
@@ -909,7 +876,6 @@
utils.Export(function(to) {
to.ExpandReplacement = ExpandReplacement;
- to.StringCharAt = StringCharAtJS;
to.StringIndexOf = StringIndexOf;
to.StringLastIndexOf = StringLastIndexOf;
to.StringMatch = StringMatchJS;
diff --git a/src/js/typedarray.js b/src/js/typedarray.js
index 4fb174b..18f6dde 100644
--- a/src/js/typedarray.js
+++ b/src/js/typedarray.js
@@ -11,7 +11,6 @@
// -------------------------------------------------------------------
// Imports
-var AddIndexedProperty;
// array.js has to come before typedarray.js for this to work
var ArrayToString = utils.ImportNow("ArrayToString");
var ArrayValues;
@@ -22,7 +21,6 @@
var GlobalArrayBufferPrototype = GlobalArrayBuffer.prototype;
var GlobalDataView = global.DataView;
var GlobalObject = global.Object;
-var InternalArray = utils.InternalArray;
var InnerArrayCopyWithin;
var InnerArrayEvery;
var InnerArrayFill;
@@ -71,7 +69,6 @@
TYPED_ARRAYS(DECLARE_GLOBALS)
utils.Import(function(from) {
- AddIndexedProperty = from.AddIndexedProperty;
ArrayValues = from.ArrayValues;
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
diff --git a/src/js/uri.js b/src/js/uri.js
index dca83c9..19bfbd3 100644
--- a/src/js/uri.js
+++ b/src/js/uri.js
@@ -37,72 +37,6 @@
return -1;
}
-// Does the char code correspond to an alpha-numeric char.
-function isAlphaNumeric(cc) {
- // a - z
- if (97 <= cc && cc <= 122) return true;
- // A - Z
- if (65 <= cc && cc <= 90) return true;
- // 0 - 9
- if (48 <= cc && cc <= 57) return true;
-
- return false;
-}
-
-// Lazily initialized.
-var hexCharCodeArray = 0;
-
-function URIAddEncodedOctetToBuffer(octet, result, index) {
- result[index++] = 37; // Char code of '%'.
- result[index++] = hexCharCodeArray[octet >> 4];
- result[index++] = hexCharCodeArray[octet & 0x0F];
- return index;
-}
-
-function URIEncodeOctets(octets, result, index) {
- if (hexCharCodeArray === 0) {
- hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 65, 66, 67, 68, 69, 70];
- }
- index = URIAddEncodedOctetToBuffer(octets[0], result, index);
- if (octets[1]) index = URIAddEncodedOctetToBuffer(octets[1], result, index);
- if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index);
- if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index);
- return index;
-}
-
-function URIEncodeSingle(cc, result, index) {
- var x = (cc >> 12) & 0xF;
- var y = (cc >> 6) & 63;
- var z = cc & 63;
- var octets = new InternalArray(3);
- if (cc <= 0x007F) {
- octets[0] = cc;
- } else if (cc <= 0x07FF) {
- octets[0] = y + 192;
- octets[1] = z + 128;
- } else {
- octets[0] = x + 224;
- octets[1] = y + 128;
- octets[2] = z + 128;
- }
- return URIEncodeOctets(octets, result, index);
-}
-
-function URIEncodePair(cc1 , cc2, result, index) {
- var u = ((cc1 >> 6) & 0xF) + 1;
- var w = (cc1 >> 2) & 0xF;
- var x = cc1 & 3;
- var y = (cc2 >> 6) & 0xF;
- var z = cc2 & 63;
- var octets = new InternalArray(4);
- octets[0] = (u >> 2) + 240;
- octets[1] = (((u & 3) << 4) | w) + 128;
- octets[2] = ((x << 4) | y) + 128;
- octets[3] = z + 128;
- return URIEncodeOctets(octets, result, index);
-}
-
function URIHexCharsToCharCode(highChar, lowChar) {
var highCode = HexValueOf(highChar);
var lowCode = HexValueOf(lowChar);
@@ -168,37 +102,6 @@
}
// ECMA-262, section 15.1.3
-function Encode(uri, unescape) {
- uri = TO_STRING(uri);
- var uriLength = uri.length;
- var array = new InternalArray(uriLength);
- var index = 0;
- for (var k = 0; k < uriLength; k++) {
- var cc1 = %_StringCharCodeAt(uri, k);
- if (unescape(cc1)) {
- array[index++] = cc1;
- } else {
- if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw MakeURIError();
- if (cc1 < 0xD800 || cc1 > 0xDBFF) {
- index = URIEncodeSingle(cc1, array, index);
- } else {
- k++;
- if (k == uriLength) throw MakeURIError();
- var cc2 = %_StringCharCodeAt(uri, k);
- if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw MakeURIError();
- index = URIEncodePair(cc1, cc2, array, index);
- }
- }
- }
-
- var result = %NewString(array.length, NEW_ONE_BYTE_STRING);
- for (var i = 0; i < array.length; i++) {
- %_OneByteSeqStringSetChar(i, array[i], result);
- }
- return result;
-}
-
-// ECMA-262, section 15.1.3
function Decode(uri, reserved) {
uri = TO_STRING(uri);
var uriLength = uri.length;
@@ -316,52 +219,6 @@
return Decode(component, reservedPredicate);
}
-// ECMA-262 - 15.1.3.3.
-function URIEncode(uri) {
- var unescapePredicate = function(cc) {
- if (isAlphaNumeric(cc)) return true;
- // !
- if (cc == 33) return true;
- // #$
- if (35 <= cc && cc <= 36) return true;
- // &'()*+,-./
- if (38 <= cc && cc <= 47) return true;
- // :;
- if (58 <= cc && cc <= 59) return true;
- // =
- if (cc == 61) return true;
- // ?@
- if (63 <= cc && cc <= 64) return true;
- // _
- if (cc == 95) return true;
- // ~
- if (cc == 126) return true;
-
- return false;
- };
- return Encode(uri, unescapePredicate);
-}
-
-// ECMA-262 - 15.1.3.4
-function URIEncodeComponent(component) {
- var unescapePredicate = function(cc) {
- if (isAlphaNumeric(cc)) return true;
- // !
- if (cc == 33) return true;
- // '()*
- if (39 <= cc && cc <= 42) return true;
- // -.
- if (45 <= cc && cc <= 46) return true;
- // _
- if (cc == 95) return true;
- // ~
- if (cc == 126) return true;
-
- return false;
- };
- return Encode(component, unescapePredicate);
-}
-
// -------------------------------------------------------------------
// Install exported functions.
@@ -371,9 +228,7 @@
"escape", URIEscapeJS,
"unescape", URIUnescapeJS,
"decodeURI", URIDecode,
- "decodeURIComponent", URIDecodeComponent,
- "encodeURI", URIEncode,
- "encodeURIComponent", URIEncodeComponent
+ "decodeURIComponent", URIDecodeComponent
]);
})
diff --git a/src/js/v8natives.js b/src/js/v8natives.js
index 5185c62..44be941 100644
--- a/src/js/v8natives.js
+++ b/src/js/v8natives.js
@@ -20,9 +20,6 @@
var MathAbs;
var NaN = %GetRootNaN();
var ObjectToString = utils.ImportNow("object_to_string");
-var ObserveBeginPerformSplice;
-var ObserveEndPerformSplice;
-var ObserveEnqueueSpliceRecord;
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
utils.Import(function(from) {
@@ -30,9 +27,6 @@
MakeSyntaxError = from.MakeSyntaxError;
MakeTypeError = from.MakeTypeError;
MathAbs = from.MathAbs;
- ObserveBeginPerformSplice = from.ObserveBeginPerformSplice;
- ObserveEndPerformSplice = from.ObserveEndPerformSplice;
- ObserveEnqueueSpliceRecord = from.ObserveEnqueueSpliceRecord;
});
// ----------------------------------------------------------------------------
@@ -148,348 +142,6 @@
return %PropertyIsEnumerable(TO_OBJECT(this), P);
}
-
-// Extensions for providing property getters and setters.
-function ObjectDefineGetter(name, fun) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectDefineGetter);
- }
- if (!IS_CALLABLE(fun)) {
- throw MakeTypeError(kObjectGetterExpectingFunction);
- }
- var desc = new PropertyDescriptor();
- desc.setGet(fun);
- desc.setEnumerable(true);
- desc.setConfigurable(true);
- DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupGetter(name) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectLookupGetter);
- }
- return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), GETTER);
-}
-
-
-function ObjectDefineSetter(name, fun) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectDefineSetter);
- }
- if (!IS_CALLABLE(fun)) {
- throw MakeTypeError(kObjectSetterExpectingFunction);
- }
- var desc = new PropertyDescriptor();
- desc.setSet(fun);
- desc.setEnumerable(true);
- desc.setConfigurable(true);
- DefineOwnProperty(TO_OBJECT(receiver), TO_NAME(name), desc, false);
-}
-
-
-function ObjectLookupSetter(name) {
- var receiver = this;
- if (IS_NULL(receiver) || IS_UNDEFINED(receiver)) {
- receiver = %GlobalProxy(ObjectLookupSetter);
- }
- return %LookupAccessor(TO_OBJECT(receiver), TO_NAME(name), SETTER);
-}
-
-
-// ES6 6.2.4.1
-function IsAccessorDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return desc.hasGetter() || desc.hasSetter();
-}
-
-
-// ES6 6.2.4.2
-function IsDataDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return desc.hasValue() || desc.hasWritable();
-}
-
-
-// ES6 6.2.4.3
-function IsGenericDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return false;
- return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
-}
-
-
-function IsInconsistentDescriptor(desc) {
- return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
-}
-
-
-// Harmony Proxies
-function FromGenericPropertyDescriptor(desc) {
- if (IS_UNDEFINED(desc)) return desc;
- var obj = new GlobalObject();
-
- if (desc.hasValue()) {
- %AddNamedProperty(obj, "value", desc.getValue(), NONE);
- }
- if (desc.hasWritable()) {
- %AddNamedProperty(obj, "writable", desc.isWritable(), NONE);
- }
- if (desc.hasGetter()) {
- %AddNamedProperty(obj, "get", desc.getGet(), NONE);
- }
- if (desc.hasSetter()) {
- %AddNamedProperty(obj, "set", desc.getSet(), NONE);
- }
- if (desc.hasEnumerable()) {
- %AddNamedProperty(obj, "enumerable", desc.isEnumerable(), NONE);
- }
- if (desc.hasConfigurable()) {
- %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE);
- }
- return obj;
-}
-
-
-// ES6 6.2.4.5
-function ToPropertyDescriptor(obj) {
- if (!IS_RECEIVER(obj)) throw MakeTypeError(kPropertyDescObject, obj);
-
- var desc = new PropertyDescriptor();
-
- if ("enumerable" in obj) {
- desc.setEnumerable(TO_BOOLEAN(obj.enumerable));
- }
-
- if ("configurable" in obj) {
- desc.setConfigurable(TO_BOOLEAN(obj.configurable));
- }
-
- if ("value" in obj) {
- desc.setValue(obj.value);
- }
-
- if ("writable" in obj) {
- desc.setWritable(TO_BOOLEAN(obj.writable));
- }
-
- if ("get" in obj) {
- var get = obj.get;
- if (!IS_UNDEFINED(get) && !IS_CALLABLE(get)) {
- throw MakeTypeError(kObjectGetterCallable, get);
- }
- desc.setGet(get);
- }
-
- if ("set" in obj) {
- var set = obj.set;
- if (!IS_UNDEFINED(set) && !IS_CALLABLE(set)) {
- throw MakeTypeError(kObjectSetterCallable, set);
- }
- desc.setSet(set);
- }
-
- if (IsInconsistentDescriptor(desc)) {
- throw MakeTypeError(kValueAndAccessor, obj);
- }
- return desc;
-}
-
-// TODO(cbruni): remove once callers have been removed
-function ToCompletePropertyDescriptor(obj) {
- var desc = ToPropertyDescriptor(obj);
- if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
- if (!desc.hasValue()) desc.setValue(UNDEFINED);
- if (!desc.hasWritable()) desc.setWritable(false);
- } else {
- // Is accessor descriptor.
- if (!desc.hasGetter()) desc.setGet(UNDEFINED);
- if (!desc.hasSetter()) desc.setSet(UNDEFINED);
- }
- if (!desc.hasEnumerable()) desc.setEnumerable(false);
- if (!desc.hasConfigurable()) desc.setConfigurable(false);
- return desc;
-}
-
-
-function PropertyDescriptor() {
- // Initialize here so they are all in-object and have the same map.
- // Default values from ES5 8.6.1.
- this.value_ = UNDEFINED;
- this.hasValue_ = false;
- this.writable_ = false;
- this.hasWritable_ = false;
- this.enumerable_ = false;
- this.hasEnumerable_ = false;
- this.configurable_ = false;
- this.hasConfigurable_ = false;
- this.get_ = UNDEFINED;
- this.hasGetter_ = false;
- this.set_ = UNDEFINED;
- this.hasSetter_ = false;
-}
-
-utils.SetUpLockedPrototype(PropertyDescriptor, [
- "value_",
- "hasValue_",
- "writable_",
- "hasWritable_",
- "enumerable_",
- "hasEnumerable_",
- "configurable_",
- "hasConfigurable_",
- "get_",
- "hasGetter_",
- "set_",
- "hasSetter_"
-], [
- "toString", function PropertyDescriptor_ToString() {
- return "[object PropertyDescriptor]";
- },
- "setValue", function PropertyDescriptor_SetValue(value) {
- this.value_ = value;
- this.hasValue_ = true;
- },
- "getValue", function PropertyDescriptor_GetValue() {
- return this.value_;
- },
- "hasValue", function PropertyDescriptor_HasValue() {
- return this.hasValue_;
- },
- "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
- this.enumerable_ = enumerable;
- this.hasEnumerable_ = true;
- },
- "isEnumerable", function PropertyDescriptor_IsEnumerable() {
- return this.enumerable_;
- },
- "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
- return this.hasEnumerable_;
- },
- "setWritable", function PropertyDescriptor_SetWritable(writable) {
- this.writable_ = writable;
- this.hasWritable_ = true;
- },
- "isWritable", function PropertyDescriptor_IsWritable() {
- return this.writable_;
- },
- "hasWritable", function PropertyDescriptor_HasWritable() {
- return this.hasWritable_;
- },
- "setConfigurable",
- function PropertyDescriptor_SetConfigurable(configurable) {
- this.configurable_ = configurable;
- this.hasConfigurable_ = true;
- },
- "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
- return this.hasConfigurable_;
- },
- "isConfigurable", function PropertyDescriptor_IsConfigurable() {
- return this.configurable_;
- },
- "setGet", function PropertyDescriptor_SetGetter(get) {
- this.get_ = get;
- this.hasGetter_ = true;
- },
- "getGet", function PropertyDescriptor_GetGetter() {
- return this.get_;
- },
- "hasGetter", function PropertyDescriptor_HasGetter() {
- return this.hasGetter_;
- },
- "setSet", function PropertyDescriptor_SetSetter(set) {
- this.set_ = set;
- this.hasSetter_ = true;
- },
- "getSet", function PropertyDescriptor_GetSetter() {
- return this.set_;
- },
- "hasSetter", function PropertyDescriptor_HasSetter() {
- return this.hasSetter_;
- }
-]);
-
-
-// Converts an array returned from Runtime_GetOwnProperty to an actual
-// property descriptor. For a description of the array layout please
-// see the runtime.cc file.
-function ConvertDescriptorArrayToDescriptor(desc_array) {
- if (IS_UNDEFINED(desc_array)) {
- return UNDEFINED;
- }
-
- var desc = new PropertyDescriptor();
- // This is an accessor.
- if (desc_array[IS_ACCESSOR_INDEX]) {
- desc.setGet(desc_array[GETTER_INDEX]);
- desc.setSet(desc_array[SETTER_INDEX]);
- } else {
- desc.setValue(desc_array[VALUE_INDEX]);
- desc.setWritable(desc_array[WRITABLE_INDEX]);
- }
- desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
- desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
-
- return desc;
-}
-
-
-// For Harmony proxies.
-function GetTrap(handler, name, defaultTrap) {
- var trap = handler[name];
- if (IS_UNDEFINED(trap)) {
- if (IS_UNDEFINED(defaultTrap)) {
- throw MakeTypeError(kIllegalInvocation);
- }
- trap = defaultTrap;
- } else if (!IS_CALLABLE(trap)) {
- throw MakeTypeError(kIllegalInvocation);
- }
- return trap;
-}
-
-
-function CallTrap1(handler, name, defaultTrap, x) {
- return %_Call(GetTrap(handler, name, defaultTrap), handler, x);
-}
-
-
-function CallTrap2(handler, name, defaultTrap, x, y) {
- return %_Call(GetTrap(handler, name, defaultTrap), handler, x, y);
-}
-
-
-// ES5 section 8.12.1.
-// TODO(jkummerow): Deprecated. Migrate all callers to
-// ObjectGetOwnPropertyDescriptor and delete this.
-function GetOwnPropertyJS(obj, v) {
- var p = TO_NAME(v);
- if (IS_PROXY(obj)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(v)) return UNDEFINED;
-
- var handler = %JSProxyGetHandler(obj);
- var descriptor = CallTrap1(
- handler, "getOwnPropertyDescriptor", UNDEFINED, p);
- if (IS_UNDEFINED(descriptor)) return descriptor;
- var desc = ToCompletePropertyDescriptor(descriptor);
- if (!desc.isConfigurable()) {
- throw MakeTypeError(kIllegalInvocation);
- }
- return desc;
- }
-
- // GetOwnProperty returns an array indexed by the constants
- // defined in macros.py.
- // If p is not a property on obj undefined is returned.
- var props = %GetOwnProperty_Legacy(TO_OBJECT(obj), p);
-
- return ConvertDescriptorArrayToDescriptor(props);
-}
-
-
// ES6 7.3.9
function GetMethod(obj, p) {
var func = obj[p];
@@ -498,252 +150,6 @@
throw MakeTypeError(kCalledNonCallable, typeof func);
}
-
-// Harmony proxies.
-function DefineProxyProperty(obj, p, attributes, should_throw) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(p)) return false;
-
- var handler = %JSProxyGetHandler(obj);
- var result = CallTrap2(handler, "defineProperty", UNDEFINED, p, attributes);
- if (!result) {
- if (should_throw) {
- throw MakeTypeError(kIllegalInvocation);
- } else {
- return false;
- }
- }
- return true;
-}
-
-
-// ES6 9.1.6 [[DefineOwnProperty]](P, Desc)
-function DefineObjectProperty(obj, p, desc, should_throw) {
- var current_array = %GetOwnProperty_Legacy(obj, TO_NAME(p));
- var current = ConvertDescriptorArrayToDescriptor(current_array);
- var extensible = %object_is_extensible(obj);
-
- if (IS_UNDEFINED(current) && !extensible) {
- if (should_throw) {
- throw MakeTypeError(kDefineDisallowed, p);
- } else {
- return false;
- }
- }
-
- if (!IS_UNDEFINED(current)) {
- if ((IsGenericDescriptor(desc) ||
- IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
- (!desc.hasEnumerable() ||
- %SameValue(desc.isEnumerable(), current.isEnumerable())) &&
- (!desc.hasConfigurable() ||
- %SameValue(desc.isConfigurable(), current.isConfigurable())) &&
- (!desc.hasWritable() ||
- %SameValue(desc.isWritable(), current.isWritable())) &&
- (!desc.hasValue() ||
- %SameValue(desc.getValue(), current.getValue())) &&
- (!desc.hasGetter() ||
- %SameValue(desc.getGet(), current.getGet())) &&
- (!desc.hasSetter() ||
- %SameValue(desc.getSet(), current.getSet()))) {
- return true;
- }
- if (!current.isConfigurable()) {
- // Step 7
- if (desc.isConfigurable() ||
- (desc.hasEnumerable() &&
- desc.isEnumerable() != current.isEnumerable())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- // Step 8
- if (!IsGenericDescriptor(desc)) {
- // Step 9a
- if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- // Step 10a
- if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
- var currentIsWritable = current.isWritable();
- if (currentIsWritable != desc.isWritable()) {
- if (!currentIsWritable) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- if (!currentIsWritable && desc.hasValue() &&
- !%SameValue(desc.getValue(), current.getValue())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- // Step 11
- if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
- if (desc.hasSetter() &&
- !%SameValue(desc.getSet(), current.getSet())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- if (desc.hasGetter() && !%SameValue(desc.getGet(),current.getGet())) {
- if (should_throw) {
- throw MakeTypeError(kRedefineDisallowed, p);
- } else {
- return false;
- }
- }
- }
- }
- }
- }
-
- // Send flags - enumerable and configurable are common - writable is
- // only send to the data descriptor.
- // Take special care if enumerable and configurable is not defined on
- // desc (we need to preserve the existing values from current).
- var flag = NONE;
- if (desc.hasEnumerable()) {
- flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isEnumerable() ? 0 : DONT_ENUM;
- } else {
- flag |= DONT_ENUM;
- }
-
- if (desc.hasConfigurable()) {
- flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isConfigurable() ? 0 : DONT_DELETE;
- } else
- flag |= DONT_DELETE;
-
- if (IsDataDescriptor(desc) ||
- (IsGenericDescriptor(desc) &&
- (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
- // There are 3 cases that lead here:
- // Step 4a - defining a new data property.
- // Steps 9b & 12 - replacing an existing accessor property with a data
- // property.
- // Step 12 - updating an existing data property with a data or generic
- // descriptor.
-
- if (desc.hasWritable()) {
- flag |= desc.isWritable() ? 0 : READ_ONLY;
- } else if (!IS_UNDEFINED(current)) {
- flag |= current.isWritable() ? 0 : READ_ONLY;
- } else {
- flag |= READ_ONLY;
- }
-
- var value = UNDEFINED; // Default value is undefined.
- if (desc.hasValue()) {
- value = desc.getValue();
- } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
- value = current.getValue();
- }
-
- %DefineDataPropertyUnchecked(obj, p, value, flag);
- } else {
- // There are 3 cases that lead here:
- // Step 4b - defining a new accessor property.
- // Steps 9c & 12 - replacing an existing data property with an accessor
- // property.
- // Step 12 - updating an existing accessor property with an accessor
- // descriptor.
- var getter = null;
- if (desc.hasGetter()) {
- getter = desc.getGet();
- } else if (IsAccessorDescriptor(current) && current.hasGetter()) {
- getter = current.getGet();
- }
- var setter = null;
- if (desc.hasSetter()) {
- setter = desc.getSet();
- } else if (IsAccessorDescriptor(current) && current.hasSetter()) {
- setter = current.getSet();
- }
- %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag);
- }
- return true;
-}
-
-
-// ES5 section 15.4.5.1.
-function DefineArrayProperty(obj, p, desc, should_throw) {
- // Step 3 - Special handling for array index.
- if (!IS_SYMBOL(p)) {
- var index = TO_UINT32(p);
- var emit_splice = false;
- if (TO_STRING(index) == p && index != 4294967295) {
- var length = obj.length;
- if (index >= length && %IsObserved(obj)) {
- emit_splice = true;
- ObserveBeginPerformSplice(obj);
- }
-
- var length_desc = GetOwnPropertyJS(obj, "length");
- if ((index >= length && !length_desc.isWritable()) ||
- !DefineObjectProperty(obj, p, desc, true)) {
- if (emit_splice)
- ObserveEndPerformSplice(obj);
- if (should_throw) {
- throw MakeTypeError(kDefineDisallowed, p);
- } else {
- return false;
- }
- }
- if (index >= length) {
- obj.length = index + 1;
- }
- if (emit_splice) {
- ObserveEndPerformSplice(obj);
- ObserveEnqueueSpliceRecord(obj, length, [], index + 1 - length);
- }
- return true;
- }
- }
-
- // Step 5 - Fallback to default implementation.
- return DefineObjectProperty(obj, p, desc, should_throw);
-}
-
-
-// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
-function DefineOwnProperty(obj, p, desc, should_throw) {
- if (IS_PROXY(obj)) {
- // TODO(rossberg): adjust once there is a story for symbols vs proxies.
- if (IS_SYMBOL(p)) return false;
-
- var attributes = FromGenericPropertyDescriptor(desc);
- return DefineProxyProperty(obj, p, attributes, should_throw);
- } else if (IS_ARRAY(obj)) {
- return DefineArrayProperty(obj, p, desc, should_throw);
- } else {
- return DefineObjectProperty(obj, p, desc, should_throw);
- }
-}
-
-
-// ES6 section 19.1.2.9
-function ObjectGetPrototypeOf(obj) {
- return %_GetPrototype(TO_OBJECT(obj));
-}
-
// ES6 section 19.1.2.18.
function ObjectSetPrototypeOf(obj, proto) {
CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");
@@ -759,50 +165,9 @@
return obj;
}
-
-// ES5 section 15.2.3.6.
-function ObjectDefineProperty(obj, p, attributes) {
- // The new pure-C++ implementation doesn't support O.o.
- // TODO(jkummerow): Implement missing features and remove fallback path.
- if (%IsObserved(obj)) {
- if (!IS_RECEIVER(obj)) {
- throw MakeTypeError(kCalledOnNonObject, "Object.defineProperty");
- }
- var name = TO_NAME(p);
- var desc = ToPropertyDescriptor(attributes);
- DefineOwnProperty(obj, name, desc, true);
- return obj;
- }
- return %ObjectDefineProperty(obj, p, attributes);
-}
-
-
-// ES5 section 15.2.3.7.
-function ObjectDefineProperties(obj, properties) {
- // The new pure-C++ implementation doesn't support O.o.
- // TODO(jkummerow): Implement missing features and remove fallback path.
- if (%IsObserved(obj)) {
- if (!IS_RECEIVER(obj)) {
- throw MakeTypeError(kCalledOnNonObject, "Object.defineProperties");
- }
- var props = TO_OBJECT(properties);
- var names = %GetOwnPropertyKeys(props, PROPERTY_FILTER_ONLY_ENUMERABLE);
- var descriptors = new InternalArray();
- for (var i = 0; i < names.length; i++) {
- descriptors.push(ToPropertyDescriptor(props[names[i]]));
- }
- for (var i = 0; i < names.length; i++) {
- DefineOwnProperty(obj, names[i], descriptors[i], true);
- }
- return obj;
- }
- return %ObjectDefineProperties(obj, properties);
-}
-
-
// ES6 B.2.2.1.1
function ObjectGetProto() {
- return %_GetPrototype(TO_OBJECT(this));
+ return %object_get_prototype_of(this);
}
@@ -842,26 +207,19 @@
"valueOf", ObjectValueOf,
"isPrototypeOf", ObjectIsPrototypeOf,
"propertyIsEnumerable", ObjectPropertyIsEnumerable,
- "__defineGetter__", ObjectDefineGetter,
- "__lookupGetter__", ObjectLookupGetter,
- "__defineSetter__", ObjectDefineSetter,
- "__lookupSetter__", ObjectLookupSetter
+ // __defineGetter__ is added in bootstrapper.cc.
+ // __lookupGetter__ is added in bootstrapper.cc.
+ // __defineSetter__ is added in bootstrapper.cc.
+ // __lookupSetter__ is added in bootstrapper.cc.
]);
-utils.InstallGetterSetter(GlobalObject.prototype, "__proto__", ObjectGetProto,
- ObjectSetProto);
+utils.InstallGetterSetter(
+ GlobalObject.prototype, "__proto__", ObjectGetProto, ObjectSetProto);
// Set up non-enumerable functions in the Object object.
utils.InstallFunctions(GlobalObject, DONT_ENUM, [
- // assign is added in bootstrapper.cc.
- // keys is added in bootstrapper.cc.
- "defineProperty", ObjectDefineProperty,
- "defineProperties", ObjectDefineProperties,
- "getPrototypeOf", ObjectGetPrototypeOf,
"setPrototypeOf", ObjectSetPrototypeOf,
// getOwnPropertySymbols is added in symbol.js.
- // is is added in bootstrapper.cc.
- // deliverChangeRecords, getNotifier, observe and unobserve are added
- // in object-observe.js.
+ // Others are added in bootstrapper.cc.
]);
@@ -1096,8 +454,6 @@
to.IsNaN = GlobalIsNaN;
to.NumberIsNaN = NumberIsNaN;
to.NumberIsInteger = NumberIsInteger;
- to.ObjectDefineProperties = ObjectDefineProperties;
- to.ObjectDefineProperty = ObjectDefineProperty;
to.ObjectHasOwnProperty = GlobalObject.prototype.hasOwnProperty;
});