 Chromium Code Reviews
 Chromium Code Reviews Issue 2680153005:
  [builtins] Array.prototype.filter implemented as a TurboFan code stub.  (Closed)
    
  
    Issue 2680153005:
  [builtins] Array.prototype.filter implemented as a TurboFan code stub.  (Closed) 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/builtins/builtins-utils-gen.h" | 5 #include "src/builtins/builtins-utils-gen.h" | 
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" | 
| 7 #include "src/code-stub-assembler.h" | 7 #include "src/code-stub-assembler.h" | 
| 8 | 8 | 
| 9 namespace v8 { | 9 namespace v8 { | 
| 10 namespace internal { | 10 namespace internal { | 
| 11 | 11 | 
| 12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { | 12 class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { | 
| 13 public: | 13 public: | 
| 14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) | 14 explicit ArrayBuiltinCodeStubAssembler(compiler::CodeAssemblerState* state) | 
| 15 : CodeStubAssembler(state) {} | 15 : CodeStubAssembler(state), to_(this, OptimalParameterRepresentation()) { | 
| 16 to_.Bind(IntPtrOrSmiConstant(0, OptimalParameterMode())); | |
| 17 } | |
| 16 | 18 | 
| 17 typedef std::function<Node*(Node* o, Node* len)> BuiltinResultGenerator; | 19 typedef std::function<Node*(Node* context, Node* o, Node* len)> | 
| 18 typedef std::function<void(Node* a, Node* pK, Node* value)> | 20 BuiltinResultGenerator; | 
| 21 typedef std::function<void(Node* context, Node* a)> | |
| 22 BuiltinResultIndexInitializer; | |
| 23 typedef std::function<void(Node* context, Node* value, Node* a, | |
| 24 Node* callback_result)> | |
| 19 CallResultProcessor; | 25 CallResultProcessor; | 
| 20 | 26 | 
| 21 void GenerateIteratingArrayBuiltinBody( | 27 void GenerateIteratingArrayBuiltinBody( | 
| 22 const char* name, const BuiltinResultGenerator& generator, | 28 const char* name, const BuiltinResultGenerator& generator, | 
| 23 const CallResultProcessor& processor, | 29 const CallResultProcessor& processor, | 
| 24 const Callable& slow_case_continuation) { | 30 const Callable& slow_case_continuation) { | 
| 25 Node* receiver = Parameter(IteratingArrayBuiltinDescriptor::kReceiver); | 31 Node* receiver = Parameter(IteratingArrayBuiltinDescriptor::kReceiver); | 
| 26 Node* callbackfn = Parameter(IteratingArrayBuiltinDescriptor::kCallback); | 32 Node* callbackfn = Parameter(IteratingArrayBuiltinDescriptor::kCallback); | 
| 27 Node* this_arg = Parameter(IteratingArrayBuiltinDescriptor::kThisArg); | 33 Node* this_arg = Parameter(IteratingArrayBuiltinDescriptor::kThisArg); | 
| 28 Node* context = Parameter(IteratingArrayBuiltinDescriptor::kContext); | 34 Node* context = Parameter(IteratingArrayBuiltinDescriptor::kContext); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 | 84 | 
| 79 Bind(&type_exception); | 85 Bind(&type_exception); | 
| 80 { | 86 { | 
| 81 CallRuntime(Runtime::kThrowTypeError, context, | 87 CallRuntime(Runtime::kThrowTypeError, context, | 
| 82 SmiConstant(MessageTemplate::kCalledNonCallable), callbackfn); | 88 SmiConstant(MessageTemplate::kCalledNonCallable), callbackfn); | 
| 83 Unreachable(); | 89 Unreachable(); | 
| 84 } | 90 } | 
| 85 | 91 | 
| 86 Bind(&done); | 92 Bind(&done); | 
| 87 | 93 | 
| 88 Node* a = generator(o, len); | 94 Node* a = generator(context, o, len); | 
| 89 | 95 | 
| 90 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. | 96 // 6. If thisArg was supplied, let T be thisArg; else let T be undefined. | 
| 91 // [Already done by the arguments adapter] | 97 // [Already done by the arguments adapter] | 
| 92 | 98 | 
| 93 HandleFastElements(context, this_arg, o, len, callbackfn, processor, a, k, | 99 HandleFastElements(context, this_arg, o, len, callbackfn, processor, a, k, | 
| 94 &slow); | 100 &slow); | 
| 95 | 101 | 
| 96 // 7. Let k be 0. | 102 // 7. Let k be 0. | 
| 97 // Already done above in initialization of the Variable k | 103 // Already done above in initialization of the Variable k | 
| 98 | 104 | 
| 99 Bind(&slow); | 105 Bind(&slow); | 
| 100 | 106 | 
| 101 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, | 107 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, | 
| 102 MachineType::TaggedPointer()); | 108 MachineType::TaggedPointer()); | 
| 103 TailCallStub( | 109 TailCallStub( | 
| 104 slow_case_continuation, context, target, new_target, | 110 slow_case_continuation, context, target, new_target, | 
| 105 Int32Constant(IteratingArrayBuiltinLoopContinuationDescriptor::kArity), | 111 Int32Constant(IteratingArrayBuiltinLoopContinuationDescriptor::kArity), | 
| 106 receiver, callbackfn, this_arg, a, o, k.value(), len); | 112 receiver, callbackfn, this_arg, a, o, k.value(), len); | 
| 107 } | 113 } | 
| 108 | 114 | 
| 109 void GenerateIteratingArrayBuiltinLoopContinuation( | 115 void GenerateIteratingArrayBuiltinLoopContinuation( | 
| 116 const BuiltinResultIndexInitializer& index_initializer, | |
| 110 const CallResultProcessor& processor) { | 117 const CallResultProcessor& processor) { | 
| 111 Node* callbackfn = | 118 Node* callbackfn = | 
| 112 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kCallback); | 119 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kCallback); | 
| 113 Node* this_arg = | 120 Node* this_arg = | 
| 114 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kThisArg); | 121 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kThisArg); | 
| 115 Node* a = | 122 Node* a = | 
| 116 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kArray); | 123 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kArray); | 
| 117 Node* o = | 124 Node* o = | 
| 118 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kObject); | 125 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kObject); | 
| 119 Node* initial_k = | 126 Node* initial_k = | 
| 120 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kInitialK); | 127 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kInitialK); | 
| 121 Node* len = | 128 Node* len = | 
| 122 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kLength); | 129 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kLength); | 
| 123 Node* context = | 130 Node* context = | 
| 124 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kContext); | 131 Parameter(IteratingArrayBuiltinLoopContinuationDescriptor::kContext); | 
| 125 | 132 | 
| 133 index_initializer(context, a); | |
| 134 | |
| 126 // 8. Repeat, while k < len | 135 // 8. Repeat, while k < len | 
| 127 Variable k(this, MachineRepresentation::kTagged, initial_k); | 136 Variable k(this, MachineRepresentation::kTagged, initial_k); | 
| 128 Label loop(this, &k); | 137 VariableList list({&k, &to_}, zone()); | 
| 138 Label loop(this, list); | |
| 129 Label after_loop(this); | 139 Label after_loop(this); | 
| 130 Goto(&loop); | 140 Goto(&loop); | 
| 131 Bind(&loop); | 141 Bind(&loop); | 
| 132 { | 142 { | 
| 133 GotoUnlessNumberLessThan(k.value(), len, &after_loop); | 143 GotoUnlessNumberLessThan(k.value(), len, &after_loop); | 
| 134 | 144 | 
| 135 Label done_element(this); | 145 Label done_element(this, &to_); | 
| 136 // a. Let Pk be ToString(k). | 146 // a. Let Pk be ToString(k). | 
| 137 Node* p_k = ToString(context, k.value()); | 147 Node* p_k = ToString(context, k.value()); | 
| 138 | 148 | 
| 139 // b. Let kPresent be HasProperty(O, Pk). | 149 // b. Let kPresent be HasProperty(O, Pk). | 
| 140 // c. ReturnIfAbrupt(kPresent). | 150 // c. ReturnIfAbrupt(kPresent). | 
| 141 Node* k_present = HasProperty(o, p_k, context); | 151 Node* k_present = HasProperty(o, p_k, context); | 
| 142 | 152 | 
| 143 // d. If kPresent is true, then | 153 // d. If kPresent is true, then | 
| 144 GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element); | 154 GotoIf(WordNotEqual(k_present, TrueConstant()), &done_element); | 
| 145 | 155 | 
| 146 // i. Let kValue be Get(O, Pk). | 156 // i. Let kValue be Get(O, Pk). | 
| 147 // ii. ReturnIfAbrupt(kValue). | 157 // ii. ReturnIfAbrupt(kValue). | 
| 148 Node* k_value = GetProperty(context, o, k.value()); | 158 Node* k_value = GetProperty(context, o, k.value()); | 
| 149 | 159 | 
| 150 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»). | 160 // iii. Let funcResult be Call(callbackfn, T, «kValue, k, O»). | 
| 151 // iv. ReturnIfAbrupt(funcResult). | 161 // iv. ReturnIfAbrupt(funcResult). | 
| 152 Node* result = CallJS(CodeFactory::Call(isolate()), context, callbackfn, | 162 Node* callback_result = | 
| 153 this_arg, k_value, k.value(), o); | 163 CallJS(CodeFactory::Call(isolate()), context, callbackfn, this_arg, | 
| 164 k_value, k.value(), o); | |
| 154 | 165 | 
| 155 processor(a, p_k, result); | 166 processor(context, k_value, a, callback_result); | 
| 156 Goto(&done_element); | 167 Goto(&done_element); | 
| 157 Bind(&done_element); | 168 Bind(&done_element); | 
| 158 | 169 | 
| 159 // e. Increase k by 1. | 170 // e. Increase k by 1. | 
| 160 k.Bind(NumberInc(k.value())); | 171 k.Bind(NumberInc(k.value())); | 
| 161 Goto(&loop); | 172 Goto(&loop); | 
| 162 } | 173 } | 
| 163 Bind(&after_loop); | 174 Bind(&after_loop); | 
| 164 Return(a); | 175 Return(a); | 
| 165 } | 176 } | 
| 166 | 177 | 
| 167 void ForEachProcessor(Node* a, Node* p_k, Node* value) {} | 178 Node* FilterResultGenerator(Node* context, Node* o, Node* len) { | 
| 179 // 7. Let A be ArraySpeciesCreate(O, 0). | |
| 180 // TODO(mvstanton): avoid this runtime call if possible. | |
| 181 Node* constructor = | |
| 182 CallRuntime(Runtime::kArraySpeciesConstructor, context, o); | |
| 183 return ConstructJS(CodeFactory::Construct(isolate()), context, constructor, | |
| 184 SmiConstant(0)); | |
| 185 } | |
| 168 | 186 | 
| 169 void SomeProcessor(Node* a, Node* p_k, Node* value) { | 187 void FilterResultIndexReinitializer(Node* context, Node* a) { | 
| 188 Variable merged_length(this, MachineRepresentation::kTagged); | |
| 189 Label has_length(this, &merged_length), not_js_array(this); | |
| 190 GotoIf(DoesntHaveInstanceType(a, JS_ARRAY_TYPE), ¬_js_array); | |
| 191 merged_length.Bind(LoadJSArrayLength(a)); | |
| 192 Goto(&has_length); | |
| 193 Bind(¬_js_array); | |
| 194 Node* len_property = | |
| 195 GetProperty(context, a, isolate()->factory()->length_string()); | |
| 
danno
2017/03/20 08:06:25
Careful, this call is observable. I don't think it
 
mvstanton
2017/03/20 16:10:53
Good catch! Actually, test262 didn't even see this
 | |
| 196 merged_length.Bind( | |
| 197 CallStub(CodeFactory::ToLength(isolate()), context, len_property)); | |
| 198 Goto(&has_length); | |
| 199 Bind(&has_length); | |
| 200 Node* len = merged_length.value(); | |
| 201 | |
| 202 to_.Bind(len); | |
| 203 } | |
| 204 | |
| 205 void ForEachProcessor(Node* context, Node* value, Node* a, | |
| 206 Node* callback_result) {} | |
| 207 | |
| 208 void SomeProcessor(Node* context, Node* value, Node* a, | |
| 209 Node* callback_result) { | |
| 170 Label false_continue(this), return_true(this); | 210 Label false_continue(this), return_true(this); | 
| 171 BranchIfToBooleanIsTrue(value, &return_true, &false_continue); | 211 BranchIfToBooleanIsTrue(callback_result, &return_true, &false_continue); | 
| 172 Bind(&return_true); | 212 Bind(&return_true); | 
| 173 Return(TrueConstant()); | 213 Return(TrueConstant()); | 
| 174 Bind(&false_continue); | 214 Bind(&false_continue); | 
| 175 } | 215 } | 
| 176 | 216 | 
| 177 void EveryProcessor(Node* a, Node* p_k, Node* value) { | 217 void EveryProcessor(Node* context, Node* value, Node* a, | 
| 218 Node* callback_result) { | |
| 178 Label true_continue(this), return_false(this); | 219 Label true_continue(this), return_false(this); | 
| 179 BranchIfToBooleanIsTrue(value, &true_continue, &return_false); | 220 BranchIfToBooleanIsTrue(callback_result, &true_continue, &return_false); | 
| 180 Bind(&return_false); | 221 Bind(&return_false); | 
| 181 Return(FalseConstant()); | 222 Return(FalseConstant()); | 
| 182 Bind(&true_continue); | 223 Bind(&true_continue); | 
| 183 } | 224 } | 
| 184 | 225 | 
| 226 void FilterProcessor(Node* context, Node* value, Node* a, | |
| 227 Node* callback_result) { | |
| 228 Label true_continue(this, &to_), false_continue(this); | |
| 229 BranchIfToBooleanIsTrue(callback_result, &true_continue, &false_continue); | |
| 230 Bind(&true_continue); | |
| 231 | |
| 232 // 1. let status be CreateDataPropertyOrThrow(A, ToString(to), kValue). | |
| 233 // 2. ReturnIfAbrupt(status) | |
| 234 Node* const p_to = ToString(context, to_.value()); | |
| 235 CallRuntime(Runtime::kCreateDataProperty, context, a, p_to, value); | |
| 236 | |
| 237 // 3. Increase to by 1. | |
| 238 to_.Bind(NumberInc(to_.value())); | |
| 239 Goto(&false_continue); | |
| 240 Bind(&false_continue); | |
| 241 } | |
| 242 | |
| 185 private: | 243 private: | 
| 186 Node* VisitAllFastElementsOneKind(Node* context, ElementsKind kind, | 244 Node* VisitAllFastElementsOneKind(Node* context, ElementsKind kind, | 
| 187 Node* this_arg, Node* o, Node* len, | 245 Node* this_arg, Node* o, Node* len, | 
| 188 Node* callbackfn, | 246 Node* callbackfn, | 
| 189 const CallResultProcessor& processor, | 247 const CallResultProcessor& processor, | 
| 190 Node* a, Label* array_changed, | 248 Node* a, Label* array_changed, | 
| 191 ParameterMode mode) { | 249 ParameterMode mode) { | 
| 192 Comment("begin VisitAllFastElementsOneKind"); | 250 Comment("begin VisitAllFastElementsOneKind"); | 
| 193 Variable original_map(this, MachineRepresentation::kTagged); | 251 Variable original_map(this, MachineRepresentation::kTagged); | 
| 194 original_map.Bind(LoadMap(o)); | 252 original_map.Bind(LoadMap(o)); | 
| 195 VariableList list({&original_map}, zone()); | 253 VariableList list({&original_map, &to_}, zone()); | 
| 196 Node* last_index = nullptr; | 254 Node* last_index = nullptr; | 
| 197 BuildFastLoop( | 255 BuildFastLoop( | 
| 198 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len, mode), | 256 list, IntPtrOrSmiConstant(0, mode), TaggedToParameter(len, mode), | 
| 199 [=, &original_map, &last_index](Node* index) { | 257 [=, &original_map, &last_index](Node* index) { | 
| 200 last_index = index; | 258 last_index = index; | 
| 201 Label one_element_done(this), hole_element(this); | 259 Label one_element_done(this), hole_element(this); | 
| 202 | 260 | 
| 203 // Check if o's map has changed during the callback. If so, we have to | 261 // Check if o's map has changed during the callback. If so, we have to | 
| 204 // fall back to the slower spec implementation for the rest of the | 262 // fall back to the slower spec implementation for the rest of the | 
| 205 // iteration. | 263 // iteration. | 
| (...skipping 18 matching lines...) Expand all Loading... | |
| 224 Node* offset = ElementOffsetFromIndex(index, kind, mode, base_size); | 282 Node* offset = ElementOffsetFromIndex(index, kind, mode, base_size); | 
| 225 Node* value = nullptr; | 283 Node* value = nullptr; | 
| 226 if (kind == FAST_ELEMENTS) { | 284 if (kind == FAST_ELEMENTS) { | 
| 227 value = LoadObjectField(elements, offset); | 285 value = LoadObjectField(elements, offset); | 
| 228 GotoIf(WordEqual(value, TheHoleConstant()), &hole_element); | 286 GotoIf(WordEqual(value, TheHoleConstant()), &hole_element); | 
| 229 } else { | 287 } else { | 
| 230 Node* double_value = | 288 Node* double_value = | 
| 231 LoadDoubleWithHoleCheck(elements, offset, &hole_element); | 289 LoadDoubleWithHoleCheck(elements, offset, &hole_element); | 
| 232 value = AllocateHeapNumberWithValue(double_value); | 290 value = AllocateHeapNumberWithValue(double_value); | 
| 233 } | 291 } | 
| 234 Node* result = CallJS(CodeFactory::Call(isolate()), context, | 292 Node* callback_result = | 
| 235 callbackfn, this_arg, value, tagged_index, o); | 293 CallJS(CodeFactory::Call(isolate()), context, callbackfn, | 
| 236 processor(a, tagged_index, result); | 294 this_arg, value, tagged_index, o); | 
| 295 processor(context, value, a, callback_result); | |
| 
danno
2017/03/20 08:06:25
Instead of adding new parameters, I think it's cle
 
mvstanton
2017/03/20 16:10:53
Yep, as per your upcoming CL. I'll leave this one
 | |
| 237 Goto(&one_element_done); | 296 Goto(&one_element_done); | 
| 238 | 297 | 
| 239 Bind(&hole_element); | 298 Bind(&hole_element); | 
| 240 // Check if o's prototype change unexpectedly has elements after the | 299 // Check if o's prototype change unexpectedly has elements after the | 
| 241 // callback in the case of a hole. | 300 // callback in the case of a hole. | 
| 242 BranchIfPrototypesHaveNoElements(o_map, &one_element_done, | 301 BranchIfPrototypesHaveNoElements(o_map, &one_element_done, | 
| 243 array_changed); | 302 array_changed); | 
| 244 | 303 | 
| 245 Bind(&one_element_done); | 304 Bind(&one_element_done); | 
| 246 }, | 305 }, | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 processor, a, &array_changed, mode); | 358 processor, a, &array_changed, mode); | 
| 300 | 359 | 
| 301 // No exception, return success | 360 // No exception, return success | 
| 302 Return(a); | 361 Return(a); | 
| 303 | 362 | 
| 304 Bind(&array_changed); | 363 Bind(&array_changed); | 
| 305 k.Bind(ParameterToTagged(last_index, mode)); | 364 k.Bind(ParameterToTagged(last_index, mode)); | 
| 306 Goto(slow); | 365 Goto(slow); | 
| 307 } | 366 } | 
| 308 } | 367 } | 
| 368 | |
| 369 Variable to_; | |
| 309 }; | 370 }; | 
| 310 | 371 | 
| 311 TF_BUILTIN(FastArrayPush, CodeStubAssembler) { | 372 TF_BUILTIN(FastArrayPush, CodeStubAssembler) { | 
| 312 Variable arg_index(this, MachineType::PointerRepresentation()); | 373 Variable arg_index(this, MachineType::PointerRepresentation()); | 
| 313 Label default_label(this, &arg_index); | 374 Label default_label(this, &arg_index); | 
| 314 Label smi_transition(this); | 375 Label smi_transition(this); | 
| 315 Label object_push_pre(this); | 376 Label object_push_pre(this); | 
| 316 Label object_push(this, &arg_index); | 377 Label object_push(this, &arg_index); | 
| 317 Label double_push(this, &arg_index); | 378 Label double_push(this, &arg_index); | 
| 318 Label double_transition(this); | 379 Label double_transition(this); | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 { | 518 { | 
| 458 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, | 519 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, | 
| 459 MachineType::TaggedPointer()); | 520 MachineType::TaggedPointer()); | 
| 460 TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target, | 521 TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target, | 
| 461 argc); | 522 argc); | 
| 462 } | 523 } | 
| 463 } | 524 } | 
| 464 | 525 | 
| 465 TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 526 TF_BUILTIN(ArrayForEachLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 
| 466 GenerateIteratingArrayBuiltinLoopContinuation( | 527 GenerateIteratingArrayBuiltinLoopContinuation( | 
| 467 [this](Node* a, Node* p_k, Node* value) { | 528 [this](Node* context, Node* a) {}, | 
| 468 ForEachProcessor(a, p_k, value); | 529 [this](Node* context, Node* value, Node* a, Node* callback_result) { | 
| 530 ForEachProcessor(context, value, a, callback_result); | |
| 531 }); | |
| 532 } | |
| 533 | |
| 534 TF_BUILTIN(ArrayFilter, ArrayBuiltinCodeStubAssembler) { | |
| 535 GenerateIteratingArrayBuiltinBody( | |
| 536 "Array.prototype.filter", | |
| 537 [=](Node* context, Node* o, Node* len) { | |
| 538 return FilterResultGenerator(context, o, len); | |
| 539 }, | |
| 540 [this](Node* context, Node* value, Node* a, Node* callback_result) { | |
| 541 FilterProcessor(context, value, a, callback_result); | |
| 542 }, | |
| 543 CodeFactory::ArrayFilterLoopContinuation(isolate())); | |
| 544 } | |
| 545 | |
| 546 TF_BUILTIN(ArrayFilterLoopContinuation, ArrayBuiltinCodeStubAssembler) { | |
| 547 GenerateIteratingArrayBuiltinLoopContinuation( | |
| 548 [this](Node* context, Node* a) { | |
| 549 FilterResultIndexReinitializer(context, a); | |
| 550 }, | |
| 551 [this](Node* context, Node* value, Node* a, Node* callback_result) { | |
| 552 FilterProcessor(context, value, a, callback_result); | |
| 469 }); | 553 }); | 
| 470 } | 554 } | 
| 471 | 555 | 
| 472 TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) { | 556 TF_BUILTIN(ArrayForEach, ArrayBuiltinCodeStubAssembler) { | 
| 473 GenerateIteratingArrayBuiltinBody( | 557 GenerateIteratingArrayBuiltinBody( | 
| 474 "Array.prototype.forEach", | 558 "Array.prototype.forEach", | 
| 475 [=](Node*, Node*) { return UndefinedConstant(); }, | 559 [=](Node*, Node*, Node*) { return UndefinedConstant(); }, | 
| 476 [this](Node* a, Node* p_k, Node* value) { | 560 [this](Node* context, Node* value, Node* a, Node* callback_result) { | 
| 477 ForEachProcessor(a, p_k, value); | 561 ForEachProcessor(context, value, a, callback_result); | 
| 478 }, | 562 }, | 
| 479 CodeFactory::ArrayForEachLoopContinuation(isolate())); | 563 CodeFactory::ArrayForEachLoopContinuation(isolate())); | 
| 480 } | 564 } | 
| 481 | 565 | 
| 482 TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 566 TF_BUILTIN(ArraySomeLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 
| 483 GenerateIteratingArrayBuiltinLoopContinuation( | 567 GenerateIteratingArrayBuiltinLoopContinuation( | 
| 484 [this](Node* a, Node* p_k, Node* value) { | 568 [](Node* context, Node* a) {}, | 
| 485 SomeProcessor(a, p_k, value); | 569 [this](Node* context, Node* value, Node* a, Node* callback_result) { | 
| 570 SomeProcessor(context, value, a, callback_result); | |
| 486 }); | 571 }); | 
| 487 } | 572 } | 
| 488 | 573 | 
| 489 TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) { | 574 TF_BUILTIN(ArraySome, ArrayBuiltinCodeStubAssembler) { | 
| 490 GenerateIteratingArrayBuiltinBody( | 575 GenerateIteratingArrayBuiltinBody( | 
| 491 "Array.prototype.some", [=](Node*, Node*) { return FalseConstant(); }, | 576 "Array.prototype.some", | 
| 492 [this](Node* a, Node* p_k, Node* value) { SomeProcessor(a, p_k, value); }, | 577 [=](Node*, Node*, Node*) { return FalseConstant(); }, | 
| 578 [this](Node* context, Node* value, Node* a, Node* callback_result) { | |
| 579 SomeProcessor(context, value, a, callback_result); | |
| 580 }, | |
| 493 CodeFactory::ArraySomeLoopContinuation(isolate())); | 581 CodeFactory::ArraySomeLoopContinuation(isolate())); | 
| 494 } | 582 } | 
| 495 | 583 | 
| 496 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 584 TF_BUILTIN(ArrayEveryLoopContinuation, ArrayBuiltinCodeStubAssembler) { | 
| 497 GenerateIteratingArrayBuiltinLoopContinuation( | 585 GenerateIteratingArrayBuiltinLoopContinuation( | 
| 498 [this](Node* a, Node* p_k, Node* value) { | 586 [](Node* context, Node* a) {}, | 
| 499 EveryProcessor(a, p_k, value); | 587 [this](Node* context, Node* value, Node* a, Node* callback_result) { | 
| 588 EveryProcessor(context, value, a, callback_result); | |
| 500 }); | 589 }); | 
| 501 } | 590 } | 
| 502 | 591 | 
| 503 TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) { | 592 TF_BUILTIN(ArrayEvery, ArrayBuiltinCodeStubAssembler) { | 
| 504 GenerateIteratingArrayBuiltinBody( | 593 GenerateIteratingArrayBuiltinBody( | 
| 505 "Array.prototype.every", [=](Node*, Node*) { return TrueConstant(); }, | 594 "Array.prototype.every", | 
| 506 [this](Node* a, Node* p_k, Node* value) { | 595 [=](Node*, Node*, Node*) { return TrueConstant(); }, | 
| 507 EveryProcessor(a, p_k, value); | 596 [this](Node* context, Node* value, Node* a, Node* callback_result) { | 
| 597 EveryProcessor(context, value, a, callback_result); | |
| 508 }, | 598 }, | 
| 509 CodeFactory::ArrayEveryLoopContinuation(isolate())); | 599 CodeFactory::ArrayEveryLoopContinuation(isolate())); | 
| 510 } | 600 } | 
| 511 | 601 | 
| 512 TF_BUILTIN(ArrayIsArray, CodeStubAssembler) { | 602 TF_BUILTIN(ArrayIsArray, CodeStubAssembler) { | 
| 513 Node* object = Parameter(1); | 603 Node* object = Parameter(1); | 
| 514 Node* context = Parameter(4); | 604 Node* context = Parameter(4); | 
| 515 | 605 | 
| 516 Label call_runtime(this), return_true(this), return_false(this); | 606 Label call_runtime(this), return_true(this), return_false(this); | 
| 517 | 607 | 
| (...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1556 { | 1646 { | 
| 1557 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 1647 Node* message = SmiConstant(MessageTemplate::kDetachedOperation); | 
| 1558 CallRuntime(Runtime::kThrowTypeError, context, message, | 1648 CallRuntime(Runtime::kThrowTypeError, context, message, | 
| 1559 HeapConstant(operation)); | 1649 HeapConstant(operation)); | 
| 1560 Unreachable(); | 1650 Unreachable(); | 
| 1561 } | 1651 } | 
| 1562 } | 1652 } | 
| 1563 | 1653 | 
| 1564 } // namespace internal | 1654 } // namespace internal | 
| 1565 } // namespace v8 | 1655 } // namespace v8 | 
| OLD | NEW |