• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5namespace array {
6transitioning javascript builtin
7ArraySomeLoopEagerDeoptContinuation(
8    js-implicit context: NativeContext, receiver: JSAny)(
9    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny): JSAny {
10  // All continuation points in the optimized some implementation are
11  // after the ToObject(O) call that ensures we are dealing with a
12  // JSReceiver.
13  //
14  // Also, this great mass of casts is necessary because the signature
15  // of Torque javascript builtins requires JSAny type for all parameters
16  // other than {context}.
17  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
18  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
19  const numberK = Cast<Number>(initialK) otherwise unreachable;
20  const numberLength = Cast<Number>(length) otherwise unreachable;
21
22  return ArraySomeLoopContinuation(
23      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
24      numberLength, Undefined);
25}
26
27transitioning javascript builtin
28ArraySomeLoopLazyDeoptContinuation(
29    js-implicit context: NativeContext, receiver: JSAny)(
30    callback: JSAny, thisArg: JSAny, initialK: JSAny, length: JSAny,
31    result: JSAny): JSAny {
32  // All continuation points in the optimized some implementation are
33  // after the ToObject(O) call that ensures we are dealing with a
34  // JSReceiver.
35  const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable;
36  const callbackfn = Cast<Callable>(callback) otherwise unreachable;
37  let numberK = Cast<Number>(initialK) otherwise unreachable;
38  const numberLength = Cast<Number>(length) otherwise unreachable;
39
40  // This custom lazy deopt point is right after the callback. some() needs
41  // to pick up at the next step: if the result is true, then return,
42  // otherwise, keep going through the array starting from k + 1.
43  if (ToBoolean(result)) {
44    return True;
45  }
46
47  numberK = numberK + 1;
48
49  return ArraySomeLoopContinuation(
50      jsreceiver, callbackfn, thisArg, Undefined, jsreceiver, numberK,
51      numberLength, Undefined);
52}
53
54transitioning builtin ArraySomeLoopContinuation(implicit context: Context)(
55    _receiver: JSReceiver, callbackfn: Callable, thisArg: JSAny, _array: JSAny,
56    o: JSReceiver, initialK: Number, length: Number, _initialTo: JSAny): JSAny {
57  // 5. Let k be 0.
58  // 6. Repeat, while k < len
59  for (let k: Number = initialK; k < length; k++) {
60    // 6a. Let Pk be ! ToString(k).
61    // k is guaranteed to be a positive integer, hence ToString is
62    // side-effect free and HasProperty/GetProperty do the conversion inline.
63
64    // 6b. Let kPresent be ? HasProperty(O, Pk).
65    const kPresent: Boolean = HasProperty_Inline(o, k);
66
67    // 6c. If kPresent is true, then
68    if (kPresent == True) {
69      // 6c. i. Let kValue be ? Get(O, Pk).
70      const kValue: JSAny = GetProperty(o, k);
71
72      // 6c. ii. Perform ? Call(callbackfn, T, <kValue, k, O>).
73      const result: JSAny = Call(context, callbackfn, thisArg, kValue, k, o);
74
75      // iii. If selected is true, then...
76      if (ToBoolean(result)) {
77        return True;
78      }
79    }
80
81    // 6d. Increase k by 1. (done by the loop).
82  }
83  return False;
84}
85
86transitioning macro FastArraySome(implicit context: Context)(
87    o: JSReceiver, len: Number, callbackfn: Callable, thisArg: JSAny): JSAny
88    labels Bailout(Smi) {
89  let k: Smi = 0;
90  const smiLen = Cast<Smi>(len) otherwise goto Bailout(k);
91  const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k);
92  let fastOW = NewFastJSArrayWitness(fastO);
93
94  // Build a fast loop over the smi array.
95  for (; k < smiLen; k++) {
96    fastOW.Recheck() otherwise goto Bailout(k);
97
98    // Ensure that we haven't walked beyond a possibly updated length.
99    if (k >= fastOW.Get().length) goto Bailout(k);
100    const value: JSAny = fastOW.LoadElementNoHole(k) otherwise continue;
101    const result: JSAny =
102        Call(context, callbackfn, thisArg, value, k, fastOW.Get());
103    if (ToBoolean(result)) {
104      return True;
105    }
106  }
107  return False;
108}
109
110// https://tc39.github.io/ecma262/#sec-array.prototype.some
111transitioning javascript builtin
112ArraySome(
113    js-implicit context: NativeContext, receiver: JSAny)(...arguments): JSAny {
114  try {
115    RequireObjectCoercible(receiver, 'Array.prototype.some');
116
117    // 1. Let O be ? ToObject(this value).
118    const o: JSReceiver = ToObject_Inline(context, receiver);
119
120    // 2. Let len be ? ToLength(? Get(O, "length")).
121    const len: Number = GetLengthProperty(o);
122
123    // 3. If IsCallable(callbackfn) is false, throw a TypeError exception.
124    if (arguments.length == 0) {
125      goto TypeError;
126    }
127    const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError;
128
129    // 4. If thisArg is present, let T be thisArg; else let T be undefined.
130    const thisArg: JSAny = arguments[1];
131
132    // Special cases.
133    try {
134      return FastArraySome(o, len, callbackfn, thisArg)
135          otherwise Bailout;
136    } label Bailout(kValue: Smi) deferred {
137      return ArraySomeLoopContinuation(
138          o, callbackfn, thisArg, Undefined, o, kValue, len, Undefined);
139    }
140  } label TypeError deferred {
141    ThrowTypeError(MessageTemplate::kCalledNonCallable, arguments[0]);
142  }
143}
144}
145