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