Wrap array implementation in a function.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/1067523003

Cr-Commit-Position: refs/heads/master@{#27940}
This commit is contained in:
yangguo 2015-04-20 07:12:39 -07:00 committed by Commit bot
parent 53cc6486df
commit f66a31282a
3 changed files with 140 additions and 115 deletions

View File

@ -2,11 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var $arrayConcat;
var $arrayJoin;
var $arrayPush;
var $arrayPop;
var $arrayShift;
var $arraySlice;
var $arraySplice;
var $arrayUnshift;
(function() {
"use strict";
// This file relies on the fact that the following declarations have been made
// in runtime.js:
// var $Array = global.Array;
%CheckIsBootstrapping();
var GlobalArray = global.Array;
// -------------------------------------------------------------------
@ -418,6 +429,7 @@ function ObservedArrayPop(n) {
return value;
}
// Removes the last element from the array and returns it. See
// ECMA-262, section 15.4.4.6.
function ArrayPop() {
@ -460,6 +472,7 @@ function ObservedArrayPush() {
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() {
@ -595,6 +608,7 @@ function ObservedArrayShift(len) {
return first;
}
function ArrayShift() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.shift");
@ -627,6 +641,7 @@ function ArrayShift() {
return first;
}
function ObservedArrayUnshift() {
var len = TO_UINT32(this.length);
var num_arguments = %_ArgumentsLength();
@ -647,6 +662,7 @@ function ObservedArrayUnshift() {
return new_length;
}
function ArrayUnshift(arg1) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.unshift");
@ -1150,7 +1166,7 @@ function ArrayFilter(f, receiver) {
needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
}
var result = new $Array();
var result = new GlobalArray();
var accumulator = new InternalArray();
var accumulator_length = 0;
var is_array = IS_ARRAY(array);
@ -1264,6 +1280,7 @@ function ArrayEvery(f, receiver) {
return true;
}
function ArrayMap(f, receiver) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
@ -1280,7 +1297,7 @@ function ArrayMap(f, receiver) {
needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
}
var result = new $Array();
var result = new GlobalArray();
var accumulator = new InternalArray(length);
var is_array = IS_ARRAY(array);
var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
@ -1445,6 +1462,7 @@ function ArrayReduce(callback, current) {
return current;
}
function ArrayReduceRight(callback, current) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
@ -1490,15 +1508,13 @@ function ArrayIsArray(obj) {
// -------------------------------------------------------------------
function SetUpArray() {
%CheckIsBootstrapping();
// Set up non-enumerable constructor property on the Array.prototype
// object.
%AddNamedProperty(GlobalArray.prototype, "constructor", GlobalArray,
DONT_ENUM);
// Set up non-enumerable constructor property on the Array.prototype
// object.
%AddNamedProperty($Array.prototype, "constructor", $Array, DONT_ENUM);
// Set up unscopable properties on the Array.prototype object.
var unscopables = {
// Set up unscopable properties on the Array.prototype object.
var unscopables = {
__proto__: null,
copyWithin: true,
entries: true,
@ -1506,18 +1522,19 @@ function SetUpArray() {
find: true,
findIndex: true,
keys: true,
};
%AddNamedProperty($Array.prototype, symbolUnscopables, unscopables,
};
%AddNamedProperty(GlobalArray.prototype, symbolUnscopables, unscopables,
DONT_ENUM | READ_ONLY);
// Set up non-enumerable functions on the Array object.
InstallFunctions($Array, DONT_ENUM, [
// Set up non-enumerable functions on the Array object.
InstallFunctions(GlobalArray, DONT_ENUM, [
"isArray", ArrayIsArray
]);
]);
var specialFunctions = %SpecialArrayFunctions();
var specialFunctions = %SpecialArrayFunctions();
var getFunction = function(name, jsBuiltin, len) {
var getFunction = function(name, jsBuiltin, len) {
var f = jsBuiltin;
if (specialFunctions.hasOwnProperty(name)) {
f = specialFunctions[name];
@ -1526,13 +1543,13 @@ function SetUpArray() {
%FunctionSetLength(f, len);
}
return f;
};
};
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
// Manipulate the length of some of the functions to meet
// expectations set by ECMA-262 or Mozilla.
InstallFunctions($Array.prototype, DONT_ENUM, [
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
// Manipulate the length of some of the functions to meet
// expectations set by ECMA-262 or Mozilla.
InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"toString", getFunction("toString", ArrayToString),
"toLocaleString", getFunction("toLocaleString", ArrayToLocaleString),
"join", getFunction("join", ArrayJoin),
@ -1554,27 +1571,35 @@ function SetUpArray() {
"lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
"reduce", getFunction("reduce", ArrayReduce, 1),
"reduceRight", getFunction("reduceRight", ArrayReduceRight, 1)
]);
]);
%FinishArrayPrototypeSetup($Array.prototype);
%FinishArrayPrototypeSetup(GlobalArray.prototype);
// The internal Array prototype doesn't need to be fancy, since it's never
// exposed to user code.
// Adding only the functions that are actually used.
SetUpLockedPrototype(InternalArray, $Array(), [
// The internal Array prototype doesn't need to be fancy, since it's never
// exposed to user code.
// Adding only the functions that are actually used.
SetUpLockedPrototype(InternalArray, GlobalArray(), [
"concat", getFunction("concat", ArrayConcatJS),
"indexOf", getFunction("indexOf", ArrayIndexOf),
"join", getFunction("join", ArrayJoin),
"pop", getFunction("pop", ArrayPop),
"push", getFunction("push", ArrayPush),
"splice", getFunction("splice", ArraySplice)
]);
]);
SetUpLockedPrototype(InternalPackedArray, $Array(), [
SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
"join", getFunction("join", ArrayJoin),
"pop", getFunction("pop", ArrayPop),
"push", getFunction("push", ArrayPush)
]);
}
]);
SetUpArray();
$arrayConcat = ArrayConcatJS;
$arrayJoin = ArrayJoin;
$arrayPush = ArrayPush;
$arrayPop = ArrayPop;
$arrayShift = ArrayShift;
$arraySlice = ArraySlice;
$arraySplice = ArraySplice;
$arrayUnshift = ArrayUnshift;
})();

View File

@ -301,14 +301,14 @@ BUILTIN(ArrayPush) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "ArrayPush", args);
return CallJsBuiltin(isolate, "$arrayPush", args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
return CallJsBuiltin(isolate, "ArrayPush", args);
return CallJsBuiltin(isolate, "$arrayPush", args);
}
DCHECK(!array->map()->is_observed());
@ -411,7 +411,7 @@ BUILTIN(ArrayPop) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "ArrayPop", args);
return CallJsBuiltin(isolate, "$arrayPop", args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@ -421,7 +421,7 @@ BUILTIN(ArrayPop) {
if (len == 0) return isolate->heap()->undefined_value();
if (JSArray::HasReadOnlyLength(array)) {
return CallJsBuiltin(isolate, "ArrayPop", args);
return CallJsBuiltin(isolate, "$arrayPop", args);
}
ElementsAccessor* accessor = array->GetElementsAccessor();
@ -429,7 +429,7 @@ BUILTIN(ArrayPop) {
Handle<Object> element =
accessor->Get(array, array, new_length, elms_obj).ToHandleChecked();
if (element->IsTheHole()) {
return CallJsBuiltin(isolate, "ArrayPop", args);
return CallJsBuiltin(isolate, "$arrayPop", args);
}
RETURN_FAILURE_ON_EXCEPTION(
isolate,
@ -447,7 +447,7 @@ BUILTIN(ArrayShift) {
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj) ||
!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(*receiver))) {
return CallJsBuiltin(isolate, "ArrayShift", args);
return CallJsBuiltin(isolate, "$arrayShift", args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
@ -456,7 +456,7 @@ BUILTIN(ArrayShift) {
if (len == 0) return heap->undefined_value();
if (JSArray::HasReadOnlyLength(array)) {
return CallJsBuiltin(isolate, "ArrayShift", args);
return CallJsBuiltin(isolate, "$arrayShift", args);
}
// Get first element
@ -464,7 +464,7 @@ BUILTIN(ArrayShift) {
Handle<Object> first =
accessor->Get(array, array, 0, elms_obj).ToHandleChecked();
if (first->IsTheHole()) {
return CallJsBuiltin(isolate, "ArrayShift", args);
return CallJsBuiltin(isolate, "$arrayShift", args);
}
if (heap->CanMoveObjectStart(*elms_obj)) {
@ -498,12 +498,12 @@ BUILTIN(ArrayUnshift) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "ArrayUnshift", args);
return CallJsBuiltin(isolate, "$arrayUnshift", args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
if (!array->HasFastSmiOrObjectElements()) {
return CallJsBuiltin(isolate, "ArrayUnshift", args);
return CallJsBuiltin(isolate, "$arrayUnshift", args);
}
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
@ -513,7 +513,7 @@ BUILTIN(ArrayUnshift) {
DCHECK(to_add <= (Smi::kMaxValue - len));
if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
return CallJsBuiltin(isolate, "ArrayUnshift", args);
return CallJsBuiltin(isolate, "$arrayUnshift", args);
}
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
@ -563,12 +563,12 @@ BUILTIN(ArraySlice) {
JSArray* array = JSArray::cast(*receiver);
if (!IsJSArrayFastElementMovingAllowed(heap, array)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
if (!array->HasFastElements()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
len = Smi::cast(array->length())->value();
@ -583,24 +583,24 @@ BUILTIN(ArraySlice) {
JSObject::cast(*receiver)->map() == arguments_map;
if (!is_arguments_object_with_fast_elements) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
JSObject* object = JSObject::cast(*receiver);
if (!object->HasFastElements()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
if (!len_obj->IsSmi()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
len = Smi::cast(len_obj)->value();
if (len > object->elements()->length()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
}
@ -620,12 +620,12 @@ BUILTIN(ArraySlice) {
double start = HeapNumber::cast(arg1)->value();
if (start < kMinInt || start > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
} else if (!arg1->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
if (n_arguments > 1) {
Object* arg2 = args[2];
@ -635,12 +635,12 @@ BUILTIN(ArraySlice) {
double end = HeapNumber::cast(arg2)->value();
if (end < kMinInt || end > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
} else if (!arg2->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
}
}
@ -675,7 +675,7 @@ BUILTIN(ArraySlice) {
kind = GetPackedElementsKind(kind);
} else if (!receiver->IsJSArray()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySlice", args);
return CallJsBuiltin(isolate, "$arraySlice", args);
}
}
@ -700,7 +700,7 @@ BUILTIN(ArraySplice) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
@ -719,12 +719,12 @@ BUILTIN(ArraySplice) {
double start = HeapNumber::cast(arg1)->value();
if (start < kMinInt || start > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
} else if (!arg1->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
}
int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
@ -748,7 +748,7 @@ BUILTIN(ArraySplice) {
value = Smi::cast(arg2)->value();
} else {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
}
actual_delete_count = Min(Max(value, 0), len - actual_start);
@ -761,12 +761,12 @@ BUILTIN(ArraySplice) {
// For double mode we do not support changing the length.
if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
if (new_length != len && JSArray::HasReadOnlyLength(array)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArraySplice", args);
return CallJsBuiltin(isolate, "$arraySplice", args);
}
if (new_length == 0) {
@ -927,7 +927,7 @@ BUILTIN(ArrayConcat) {
PrototypeIterator::START_AT_RECEIVER);
if (!ArrayPrototypeHasNoElements(heap, &iter)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArrayConcatJS", args);
return CallJsBuiltin(isolate, "$arrayConcat", args);
}
// Iterate through all the arguments performing checks
@ -939,7 +939,7 @@ BUILTIN(ArrayConcat) {
if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements() ||
iter.GetCurrent() != array_proto) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArrayConcatJS", args);
return CallJsBuiltin(isolate, "$arrayConcat", args);
}
int len = Smi::cast(JSArray::cast(arg)->length())->value();
@ -952,7 +952,7 @@ BUILTIN(ArrayConcat) {
if (result_len > FixedDoubleArray::kMaxLength) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "ArrayConcatJS", args);
return CallJsBuiltin(isolate, "$arrayConcat", args);
}
ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();

View File

@ -1072,7 +1072,7 @@ function FormatStackTrace(obj, raw_stack) {
}
lines.push(" at " + line);
}
return %_CallFunction(lines, "\n", ArrayJoin);
return %_CallFunction(lines, "\n", $arrayJoin);
}