11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_cinamespace array {
61cb0ef41Sopenharmony_citransitioning javascript builtin
71cb0ef41Sopenharmony_ciArrayEveryLoopEagerDeoptContinuation(
81cb0ef41Sopenharmony_ci    js-implicit context: NativeContext, receiver: JSAny)(
91cb0ef41Sopenharmony_ci    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny {
101cb0ef41Sopenharmony_ci  // All continuation points in the optimized every implementation are
111cb0ef41Sopenharmony_ci  // after the ToObject(O) call that ensures we are dealing with a
121cb0ef41Sopenharmony_ci  // JSReceiver.
131cb0ef41Sopenharmony_ci  //
141cb0ef41Sopenharmony_ci  // Also, this great mass of casts is necessary because the signature
151cb0ef41Sopenharmony_ci  // of Torque javascript builtins requires JSAny type for all parameters
161cb0ef41Sopenharmony_ci  // other than {context}.
171cb0ef41Sopenharmony_ci  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
181cb0ef41Sopenharmony_ci  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
191cb0ef41Sopenharmony_ci  const numberK = Cast<Number>(initialK) otherwise unreachable;
201cb0ef41Sopenharmony_ci  const numberLength = Cast<Number>(length) otherwise unreachable;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  return ArrayEveryLoopContinuation(
231cb0ef41Sopenharmony_ci      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
241cb0ef41Sopenharmony_ci      numberLength, Undefined);
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_citransitioning javascript builtin
281cb0ef41Sopenharmony_ciArrayEveryLoopLazyDeoptContinuation(
291cb0ef41Sopenharmony_ci    js-implicit context: NativeContext, receiver: JSAny)(
301cb0ef41Sopenharmony_ci    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny,
311cb0ef41Sopenharmony_ci    result: JSAny): JSAny {
321cb0ef41Sopenharmony_ci  // All continuation points in the optimized every implementation are
331cb0ef41Sopenharmony_ci  // after the ToObject(O) call that ensures we are dealing with a
341cb0ef41Sopenharmony_ci  // JSReceiver.
351cb0ef41Sopenharmony_ci  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
361cb0ef41Sopenharmony_ci  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
371cb0ef41Sopenharmony_ci  let numberK = Cast<Number>(initialK) otherwise unreachable;
381cb0ef41Sopenharmony_ci  const numberLength = Cast<Number>(length) otherwise unreachable;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  // This custom lazy deopt point is right after the callback. every() needs
411cb0ef41Sopenharmony_ci  // to pick up at the next step, which is either continuing to the next
421cb0ef41Sopenharmony_ci  // array element or returning false if {result} is false.
431cb0ef41Sopenharmony_ci  if (!ToBoolean(result)) {
441cb0ef41Sopenharmony_ci    return False;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  numberK = numberK + 1;
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  return ArrayEveryLoopContinuation(
501cb0ef41Sopenharmony_ci      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
511cb0ef41Sopenharmony_ci      numberLength, Undefined);
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_citransitioning builtin ArrayEveryLoopContinuation(implicit context: Context)(
551cb0ef41Sopenharmony_ci    _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, _array: JSAny,
561cb0ef41Sopenharmony_ci    o: JSReceiver, initialK: Number, length: Number, _initialTo: JSAny): JSAny {
571cb0ef41Sopenharmony_ci  // 5. Let k be 0.
581cb0ef41Sopenharmony_ci  // 6. Repeat, while k < len
591cb0ef41Sopenharmony_ci  for (let k: Number = initialK; k < length; k++) {
601cb0ef41Sopenharmony_ci    // 6a. Let Pk be ! ToString(k).
611cb0ef41Sopenharmony_ci    // k is guaranteed to be a positive integer, hence ToString is
621cb0ef41Sopenharmony_ci    // side-effect free and HasProperty/GetProperty do the conversion inline.
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci    // 6b. Let kPresent be ? HasProperty(O, Pk).
651cb0ef41Sopenharmony_ci    const kPresent: Boolean = HasProperty_Inline(o, k);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    // 6c. If kPresent is true, then
681cb0ef41Sopenharmony_ci    if (kPresent == True) {
691cb0ef41Sopenharmony_ci      // 6c. i. Let kValue be ? Get(O, Pk).
701cb0ef41Sopenharmony_ci      const kValue: JSAny = GetProperty(o, k);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci      // 6c. ii. Perform ? Call(callbackfn, T, <kValue, k, O>).
731cb0ef41Sopenharmony_ci      const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o);
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci      // iii. If selected is true, then...
761cb0ef41Sopenharmony_ci      if (!ToBoolean(result)) {
771cb0ef41Sopenharmony_ci        return False;
781cb0ef41Sopenharmony_ci      }
791cb0ef41Sopenharmony_ci    }
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    // 6d. Increase k by 1. (done by the loop).
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci  return True;
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_citransitioning macro FastArrayEvery(implicit context: Context)(
871cb0ef41Sopenharmony_ci    o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny
881cb0ef41Sopenharmony_ci    labels Bailout(Smi) {
891cb0ef41Sopenharmony_ci  let k: Smi = 0;
901cb0ef41Sopenharmony_ci  const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
911cb0ef41Sopenharmony_ci  const fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k);
921cb0ef41Sopenharmony_ci  let fastOW = NewFastJSArrayWitness(fastO);
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci  // Build a fast loop over the smi array.
951cb0ef41Sopenharmony_ci  for (; k < smiLen; k++) {
961cb0ef41Sopenharmony_ci    fastOW.Recheck() otherwise goto Bailout(k);
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci    // Ensure that we haven't walked beyond a possibly updated length.
991cb0ef41Sopenharmony_ci    if (k >= fastOW.Get().length) goto Bailout(k);
1001cb0ef41Sopenharmony_ci    const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue;
1011cb0ef41Sopenharmony_ci    const result: JSAny =
1021cb0ef41Sopenharmony_ci        Call(context, callbackfn, thisArg, value, k, fastOW.Get());
1031cb0ef41Sopenharmony_ci    if (!ToBoolean(result)) {
1041cb0ef41Sopenharmony_ci      return False;
1051cb0ef41Sopenharmony_ci    }
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci  return True;
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci// https://tc39.github.io/ecma262/#sec-array.prototype.every
1111cb0ef41Sopenharmony_citransitioning javascript builtin
1121cb0ef41Sopenharmony_ciArrayEvery(
1131cb0ef41Sopenharmony_ci    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
1141cb0ef41Sopenharmony_ci  try {
1151cb0ef41Sopenharmony_ci    RequireObjectCoercible(receiver, 'Array.prototype.every');
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci    // 1. Let O be ? ToObject(this value).
1181cb0ef41Sopenharmony_ci    const o: JSReceiver = ToObject_Inline(context, receiver);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci    // 2. Let len be ? ToLength(? Get(O, "length")).
1211cb0ef41Sopenharmony_ci    const len: Number = GetLengthProperty(o);
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci    // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
1241cb0ef41Sopenharmony_ci    if (arguments.length == 0) {
1251cb0ef41Sopenharmony_ci      goto TypeError;
1261cb0ef41Sopenharmony_ci    }
1271cb0ef41Sopenharmony_ci    const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci    // 4. If thisArg is present, let T be thisArg; else let T be undefined.
1301cb0ef41Sopenharmony_ci    const thisArg: JSAny = arguments[1];
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci    // Special cases.
1331cb0ef41Sopenharmony_ci    try {
1341cb0ef41Sopenharmony_ci      return FastArrayEvery(o, len, callbackfn, thisArg)
1351cb0ef41Sopenharmony_ci          otherwise Bailout;
1361cb0ef41Sopenharmony_ci    } label Bailout(kValue: Smi) deferred {
1371cb0ef41Sopenharmony_ci      return ArrayEveryLoopContinuation(
1381cb0ef41Sopenharmony_ci          o, callbackfn, thisArg, Undefined, o, kValue, len, Undefined);
1391cb0ef41Sopenharmony_ci    }
1401cb0ef41Sopenharmony_ci  } label TypeError deferred {
1411cb0ef41Sopenharmony_ci    ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci}
1441cb0ef41Sopenharmony_ci}
145