Install js intrinsic fallbacks for array functions on the native context.
authoryangguo <yangguo@chromium.org>
Wed, 26 Aug 2015 12:03:56 +0000 (05:03 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 26 Aug 2015 12:04:10 +0000 (12:04 +0000)
R=cbruni@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30382}

src/array.js
src/builtins.cc
src/contexts.h
src/i18n.js

index 4520a34..af3dbd7 100644 (file)
@@ -2,14 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-var $arrayConcat;
-var $arrayPush;
-var $arrayPop;
-var $arrayShift;
-var $arraySlice;
-var $arraySplice;
-var $arrayUnshift;
-
 (function(global, utils) {
 
 "use strict";
@@ -1695,6 +1687,7 @@ utils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
 utils.Export(function(to) {
   to.ArrayIndexOf = ArrayIndexOf;
   to.ArrayJoin = ArrayJoin;
+  to.ArrayPush = ArrayPush;
   to.ArrayToString = ArrayToString;
   to.InnerArrayEvery = InnerArrayEvery;
   to.InnerArrayFilter = InnerArrayFilter;
@@ -1711,12 +1704,14 @@ utils.Export(function(to) {
   to.PackedArrayReverse = PackedArrayReverse;
 });
 
-$arrayConcat = ArrayConcatJS;
-$arrayPush = ArrayPush;
-$arrayPop = ArrayPop;
-$arrayShift = ArrayShift;
-$arraySlice = ArraySlice;
-$arraySplice = ArraySplice;
-$arrayUnshift = ArrayUnshift;
+%InstallToContext([
+  "array_concat", ArrayConcatJS,
+  "array_pop", ArrayPop,
+  "array_push", ArrayPush,
+  "array_shift", ArrayShift,
+  "array_splice", ArraySplice,
+  "array_slice", ArraySlice,
+  "array_unshift", ArrayUnshift,
+]);
 
 });
index 4bc61b8..261c583 100644 (file)
@@ -283,17 +283,10 @@ static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
 }
 
 
-MUST_USE_RESULT static Object* CallJsBuiltin(
-    Isolate* isolate,
-    const char* name,
+MUST_USE_RESULT static Object* CallJsIntrinsic(
+    Isolate* isolate, Handle<JSFunction> function,
     BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
   HandleScope handleScope(isolate);
-
-  Handle<Object> js_builtin = Object::GetProperty(
-      isolate,
-      handle(isolate->native_context()->builtins(), isolate),
-      name).ToHandleChecked();
-  Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
   int argc = args.length() - 1;
   ScopedVector<Handle<Object> > argv(argc);
   for (int i = 0; i < argc; ++i) {
@@ -318,7 +311,7 @@ BUILTIN(ArrayPush) {
       EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
   Handle<FixedArrayBase> elms_obj;
   if (!maybe_elms_obj.ToHandle(&elms_obj)) {
-    return CallJsBuiltin(isolate, "$arrayPush", args);
+    return CallJsIntrinsic(isolate, isolate->array_push(), args);
   }
   // Fast Elements Path
   int push_size = args.length() - 1;
@@ -329,7 +322,7 @@ BUILTIN(ArrayPush) {
   }
   if (push_size > 0 &&
       JSArray::WouldChangeReadOnlyLength(array, len + push_size)) {
-    return CallJsBuiltin(isolate, "$arrayPush", args);
+    return CallJsIntrinsic(isolate, isolate->array_push(), args);
   }
   DCHECK(!array->map()->is_observed());
   ElementsAccessor* accessor = array->GetElementsAccessor();
@@ -346,7 +339,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 CallJsIntrinsic(isolate, isolate->array_pop(), args);
   }
 
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@@ -356,7 +349,7 @@ BUILTIN(ArrayPop) {
   if (len == 0) return isolate->heap()->undefined_value();
 
   if (JSArray::HasReadOnlyLength(array)) {
-    return CallJsBuiltin(isolate, "$arrayPop", args);
+    return CallJsIntrinsic(isolate, isolate->array_pop(), args);
   }
 
   uint32_t new_length = len - 1;
@@ -378,7 +371,7 @@ BUILTIN(ArrayShift) {
   Handle<FixedArrayBase> elms_obj;
   if (!maybe_elms_obj.ToHandle(&elms_obj) ||
       !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
-    return CallJsBuiltin(isolate, "$arrayShift", args);
+    return CallJsIntrinsic(isolate, isolate->array_shift(), args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   DCHECK(!array->map()->is_observed());
@@ -387,7 +380,7 @@ BUILTIN(ArrayShift) {
   if (len == 0) return heap->undefined_value();
 
   if (JSArray::HasReadOnlyLength(array)) {
-    return CallJsBuiltin(isolate, "$arrayShift", args);
+    return CallJsIntrinsic(isolate, isolate->array_shift(), args);
   }
 
   // Get first element
@@ -425,12 +418,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 CallJsIntrinsic(isolate, isolate->array_unshift(), args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   DCHECK(!array->map()->is_observed());
   if (!array->HasFastSmiOrObjectElements()) {
-    return CallJsBuiltin(isolate, "$arrayUnshift", args);
+    return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
   }
   int len = Smi::cast(array->length())->value();
   int to_add = args.length() - 1;
@@ -440,7 +433,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 CallJsIntrinsic(isolate, isolate->array_unshift(), args);
   }
 
   Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
@@ -490,12 +483,12 @@ BUILTIN(ArraySlice) {
       JSArray* array = JSArray::cast(*receiver);
       if (!IsJSArrayFastElementMovingAllowed(isolate, array)) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
 
       if (!array->HasFastElements()) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
 
       len = Smi::cast(array->length())->value();
@@ -510,24 +503,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 CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
       JSObject* object = JSObject::cast(*receiver);
 
       if (!object->HasFastElements()) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
 
       Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
       if (!len_obj->IsSmi()) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
       len = Smi::cast(len_obj)->value();
       if (len > object->elements()->length()) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
     }
 
@@ -547,12 +540,12 @@ BUILTIN(ArraySlice) {
         double start = HeapNumber::cast(arg1)->value();
         if (start < kMinInt || start > kMaxInt) {
           AllowHeapAllocation allow_allocation;
-          return CallJsBuiltin(isolate, "$arraySlice", args);
+          return CallJsIntrinsic(isolate, isolate->array_slice(), args);
         }
         relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
       } else if (!arg1->IsUndefined()) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySlice", args);
+        return CallJsIntrinsic(isolate, isolate->array_slice(), args);
       }
       if (n_arguments > 1) {
         Object* arg2 = args[2];
@@ -562,12 +555,12 @@ BUILTIN(ArraySlice) {
           double end = HeapNumber::cast(arg2)->value();
           if (end < kMinInt || end > kMaxInt) {
             AllowHeapAllocation allow_allocation;
-            return CallJsBuiltin(isolate, "$arraySlice", args);
+            return CallJsIntrinsic(isolate, isolate->array_slice(), args);
           }
           relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
         } else if (!arg2->IsUndefined()) {
           AllowHeapAllocation allow_allocation;
-          return CallJsBuiltin(isolate, "$arraySlice", args);
+          return CallJsIntrinsic(isolate, isolate->array_slice(), args);
         }
       }
     }
@@ -602,7 +595,7 @@ BUILTIN(ArraySlice) {
       kind = GetPackedElementsKind(kind);
     } else if (!receiver->IsJSArray()) {
       AllowHeapAllocation allow_allocation;
-      return CallJsBuiltin(isolate, "$arraySlice", args);
+      return CallJsIntrinsic(isolate, isolate->array_slice(), args);
     }
   }
 
@@ -627,7 +620,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 CallJsIntrinsic(isolate, isolate->array_splice(), args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   DCHECK(!array->map()->is_observed());
@@ -646,12 +639,12 @@ BUILTIN(ArraySplice) {
       double start = HeapNumber::cast(arg1)->value();
       if (start < kMinInt || start > kMaxInt) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySplice", args);
+        return CallJsIntrinsic(isolate, isolate->array_splice(), args);
       }
       relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
     } else if (!arg1->IsUndefined()) {
       AllowHeapAllocation allow_allocation;
-      return CallJsBuiltin(isolate, "$arraySplice", args);
+      return CallJsIntrinsic(isolate, isolate->array_splice(), args);
     }
   }
   int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
@@ -675,7 +668,7 @@ BUILTIN(ArraySplice) {
         value = Smi::cast(arg2)->value();
       } else {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arraySplice", args);
+        return CallJsIntrinsic(isolate, isolate->array_splice(), args);
       }
     }
     actual_delete_count = Min(Max(value, 0), len - actual_start);
@@ -688,12 +681,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 CallJsIntrinsic(isolate, isolate->array_splice(), args);
   }
 
   if (new_length != len && JSArray::HasReadOnlyLength(array)) {
     AllowHeapAllocation allow_allocation;
-    return CallJsBuiltin(isolate, "$arraySplice", args);
+    return CallJsIntrinsic(isolate, isolate->array_splice(), args);
   }
 
   if (new_length == 0) {
@@ -853,7 +846,7 @@ BUILTIN(ArrayConcat) {
                            PrototypeIterator::START_AT_RECEIVER);
     if (!ArrayPrototypeHasNoElements(&iter)) {
       AllowHeapAllocation allow_allocation;
-      return CallJsBuiltin(isolate, "$arrayConcat", args);
+      return CallJsIntrinsic(isolate, isolate->array_concat(), args);
     }
 
     // Iterate through all the arguments performing checks
@@ -865,7 +858,7 @@ BUILTIN(ArrayConcat) {
       if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements() ||
           iter.GetCurrent() != array_proto) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arrayConcat", args);
+        return CallJsIntrinsic(isolate, isolate->array_concat(), args);
       }
       int len = Smi::cast(JSArray::cast(arg)->length())->value();
 
@@ -878,7 +871,7 @@ BUILTIN(ArrayConcat) {
 
       if (result_len > FixedDoubleArray::kMaxLength) {
         AllowHeapAllocation allow_allocation;
-        return CallJsBuiltin(isolate, "$arrayConcat", args);
+        return CallJsIntrinsic(isolate, isolate->array_concat(), args);
       }
 
       ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
index 1a35ed9..d41191e 100644 (file)
@@ -91,6 +91,13 @@ enum BindingFlags {
   V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun)
 
 #define NATIVE_CONTEXT_IMPORTED_FIELDS(V)                                     \
+  V(ARRAY_CONCAT_INDEX, JSFunction, array_concat)                             \
+  V(ARRAY_POP_INDEX, JSFunction, array_pop)                                   \
+  V(ARRAY_PUSH_INDEX, JSFunction, array_push)                                 \
+  V(ARRAY_SHIFT_INDEX, JSFunction, array_shift)                               \
+  V(ARRAY_SPLICE_INDEX, JSFunction, array_splice)                             \
+  V(ARRAY_SLICE_INDEX, JSFunction, array_slice)                               \
+  V(ARRAY_UNSHIFT_INDEX, JSFunction, array_unshift)                           \
   V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)           \
   V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun)                       \
   V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap)                     \
index 5fd32c8..f0bcbc3 100644 (file)
@@ -19,6 +19,7 @@
 
 var ArrayIndexOf;
 var ArrayJoin;
+var ArrayPush;
 var IsFinite;
 var IsNaN;
 var GlobalBoolean = global.Boolean;
@@ -39,6 +40,7 @@ var StringSubstring;
 utils.Import(function(from) {
   ArrayIndexOf = from.ArrayIndexOf;
   ArrayJoin = from.ArrayJoin;
+  ArrayPush = from.ArrayPush;
   IsFinite = from.IsFinite;
   IsNaN = from.IsNaN;
   MathFloor = from.MathFloor;
@@ -298,7 +300,7 @@ function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
     do {
       if (!IS_UNDEFINED(availableLocales[locale])) {
         // Push requested locale not the resolved one.
-        %_CallFunction(matchedLocales, requestedLocales[i], $arrayPush);
+        %_CallFunction(matchedLocales, requestedLocales[i], ArrayPush);
         break;
       }
       // Truncate locale if possible, if not break.
@@ -715,7 +717,7 @@ function initializeLocaleList(locales) {
   } else {
     // We allow single string localeID.
     if (typeof locales === 'string') {
-      %_CallFunction(seen, canonicalizeLanguageTag(locales), $arrayPush);
+      %_CallFunction(seen, canonicalizeLanguageTag(locales), ArrayPush);
       return freezeArray(seen);
     }
 
@@ -729,7 +731,7 @@ function initializeLocaleList(locales) {
         var tag = canonicalizeLanguageTag(value);
 
         if (%_CallFunction(seen, tag, ArrayIndexOf) === -1) {
-          %_CallFunction(seen, tag, $arrayPush);
+          %_CallFunction(seen, tag, ArrayPush);
         }
       }
     }
@@ -775,7 +777,7 @@ function isValidLanguageTag(locale) {
     if (%_CallFunction(GetLanguageVariantRE(), value, RegExpTest) &&
         extensions.length === 0) {
       if (%_CallFunction(variants, value, ArrayIndexOf) === -1) {
-        %_CallFunction(variants, value, $arrayPush);
+        %_CallFunction(variants, value, ArrayPush);
       } else {
         return false;
       }
@@ -783,7 +785,7 @@ function isValidLanguageTag(locale) {
 
     if (%_CallFunction(GetLanguageSingletonRE(), value, RegExpTest)) {
       if (%_CallFunction(extensions, value, ArrayIndexOf) === -1) {
-        %_CallFunction(extensions, value, $arrayPush);
+        %_CallFunction(extensions, value, ArrayPush);
       } else {
         return false;
       }