Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Side by Side Diff: src/builtins.cc

Issue 1321773002: Adding ElementsAccessor::Slice (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-08-10_array_builtin_splice
Patch Set: sign fix No.1 Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/elements.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 int args_length, Object** args_object, Isolate* isolate) { \ 127 int args_length, Object** args_object, Isolate* isolate) { \
128 name##ArgumentsType args(args_length, args_object); \ 128 name##ArgumentsType args(args_length, args_object); \
129 return Builtin_impl##name(args, isolate); \ 129 return Builtin_impl##name(args, isolate); \
130 } \ 130 } \
131 static Object* Builtin_impl##name( \ 131 static Object* Builtin_impl##name( \
132 name##ArgumentsType args, Isolate* isolate) 132 name##ArgumentsType args, Isolate* isolate)
133 #endif 133 #endif
134 134
135 135
136 #ifdef DEBUG 136 #ifdef DEBUG
137 static inline bool CalledAsConstructor(Isolate* isolate) { 137 inline bool CalledAsConstructor(Isolate* isolate) {
138 // Calculate the result using a full stack frame iterator and check 138 // Calculate the result using a full stack frame iterator and check
139 // that the state of the stack is as we assume it to be in the 139 // that the state of the stack is as we assume it to be in the
140 // code below. 140 // code below.
141 StackFrameIterator it(isolate); 141 StackFrameIterator it(isolate);
142 DCHECK(it.frame()->is_exit()); 142 DCHECK(it.frame()->is_exit());
143 it.Advance(); 143 it.Advance();
144 StackFrame* frame = it.frame(); 144 StackFrame* frame = it.frame();
145 bool reference_result = frame->is_construct(); 145 bool reference_result = frame->is_construct();
146 Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); 146 Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
147 // Because we know fp points to an exit frame we can use the relevant 147 // Because we know fp points to an exit frame we can use the relevant
(...skipping 10 matching lines...) Expand all
158 bool result = (marker == kConstructMarker); 158 bool result = (marker == kConstructMarker);
159 DCHECK_EQ(result, reference_result); 159 DCHECK_EQ(result, reference_result);
160 return result; 160 return result;
161 } 161 }
162 #endif 162 #endif
163 163
164 164
165 // ---------------------------------------------------------------------------- 165 // ----------------------------------------------------------------------------
166 166
167 167
168 bool ClampedToInteger(Object* object, int* out) { 168 inline bool ClampedToInteger(Object* object, int* out) {
169 // This is an extended version of ECMA-262 7.1.11 handling signed values 169 // This is an extended version of ECMA-262 7.1.11 handling signed values
170 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] 170 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt]
171 if (object->IsSmi()) { 171 if (object->IsSmi()) {
172 *out = Smi::cast(object)->value(); 172 *out = Smi::cast(object)->value();
173 return true; 173 return true;
174 } else if (object->IsHeapNumber()) { 174 } else if (object->IsHeapNumber()) {
175 *out = FastD2IChecked(HeapNumber::cast(object)->value()); 175 *out = FastD2IChecked(HeapNumber::cast(object)->value());
176 return true; 176 return true;
177 } else if (object->IsUndefined()) { 177 } else if (object->IsUndefined() || object->IsNull()) {
178 *out = 0; 178 *out = 0;
179 return true; 179 return true;
180 } else if (object->IsBoolean()) { 180 } else if (object->IsBoolean()) {
181 *out = object->IsTrue(); 181 *out = object->IsTrue();
182 return true; 182 return true;
183 } 183 }
184 return false; 184 return false;
185 } 185 }
186 186
187 187
188 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, 188 void MoveDoubleElements(FixedDoubleArray* dst, int dst_index,
189 FixedDoubleArray* src, int src_index, int len) { 189 FixedDoubleArray* src, int src_index, int len) {
190 if (len == 0) return; 190 if (len == 0) return;
191 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, 191 MemMove(dst->data_start() + dst_index, src->data_start() + src_index,
192 len * kDoubleSize); 192 len * kDoubleSize);
193 } 193 }
194 194
195 195
196 static bool ArrayPrototypeHasNoElements(PrototypeIterator* iter) { 196 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object,
197 int* out) {
198 Map* arguments_map =
199 isolate->context()->native_context()->sloppy_arguments_map();
200 if (object->map() != arguments_map || !object->HasFastElements()) {
201 return false;
202 }
203 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
204 if (!len_obj->IsSmi()) {
205 return false;
206 }
207 *out = Smi::cast(len_obj)->value();
208 return *out <= object->elements()->length();
209 }
210
211
212 bool PrototypeHasNoElements(PrototypeIterator* iter) {
197 DisallowHeapAllocation no_gc; 213 DisallowHeapAllocation no_gc;
198 for (; !iter->IsAtEnd(); iter->Advance()) { 214 for (; !iter->IsAtEnd(); iter->Advance()) {
199 if (iter->GetCurrent()->IsJSProxy()) return false; 215 if (iter->GetCurrent()->IsJSProxy()) return false;
200 JSObject* current = JSObject::cast(iter->GetCurrent()); 216 JSObject* current = JSObject::cast(iter->GetCurrent());
201 if (current->IsAccessCheckNeeded()) return false; 217 if (current->IsAccessCheckNeeded()) return false;
202 if (current->HasIndexedInterceptor()) return false; 218 if (current->HasIndexedInterceptor()) return false;
203 if (current->elements()->length() != 0) return false; 219 if (current->elements()->length() != 0) return false;
204 } 220 }
205 return true; 221 return true;
206 } 222 }
207 223
208 224
209 static inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate, 225 inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
210 JSArray* receiver) { 226 JSArray* receiver) {
211 DisallowHeapAllocation no_gc; 227 DisallowHeapAllocation no_gc;
212 // If the array prototype chain is intact (and free of elements), and if the 228 // If the array prototype chain is intact (and free of elements), and if the
213 // receiver's prototype is the array prototype, then we are done. 229 // receiver's prototype is the array prototype, then we are done.
214 Object* prototype = receiver->map()->prototype(); 230 Object* prototype = receiver->map()->prototype();
215 if (prototype->IsJSArray() && 231 if (prototype->IsJSArray() &&
216 isolate->is_initial_array_prototype(JSArray::cast(prototype)) && 232 isolate->is_initial_array_prototype(JSArray::cast(prototype)) &&
217 isolate->IsFastArrayConstructorPrototypeChainIntact()) { 233 isolate->IsFastArrayConstructorPrototypeChainIntact()) {
218 return true; 234 return true;
219 } 235 }
220 236
221 // Slow case. 237 // Slow case.
222 PrototypeIterator iter(isolate, receiver); 238 PrototypeIterator iter(isolate, receiver);
223 return ArrayPrototypeHasNoElements(&iter); 239 return PrototypeHasNoElements(&iter);
224 } 240 }
225 241
226 242
227 // Returns empty handle if not applicable. 243 // Returns empty handle if not applicable.
228 MUST_USE_RESULT 244 MUST_USE_RESULT
229 static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( 245 inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
230 Isolate* isolate, 246 Isolate* isolate, Handle<Object> receiver, Arguments* args,
231 Handle<Object> receiver,
232 Arguments* args,
233 int first_added_arg) { 247 int first_added_arg) {
234 if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>(); 248 if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
235 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 249 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
236 // If there may be elements accessors in the prototype chain, the fast path 250 // If there may be elements accessors in the prototype chain, the fast path
237 // cannot be used if there arguments to add to the array. 251 // cannot be used if there arguments to add to the array.
238 Heap* heap = isolate->heap(); 252 Heap* heap = isolate->heap();
239 if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) { 253 if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
240 return MaybeHandle<FixedArrayBase>(); 254 return MaybeHandle<FixedArrayBase>();
241 } 255 }
242 if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>(); 256 if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 } 298 }
285 } 299 }
286 } 300 }
287 if (target_kind != origin_kind) { 301 if (target_kind != origin_kind) {
288 JSObject::TransitionElementsKind(array, target_kind); 302 JSObject::TransitionElementsKind(array, target_kind);
289 return handle(array->elements(), isolate); 303 return handle(array->elements(), isolate);
290 } 304 }
291 return elms; 305 return elms;
292 } 306 }
293 307
294
Igor Sheludko 2015/08/31 10:42:51 Spurious change.
Camillo Bruni 2015/08/31 11:10:08 I moved everything in to an anonymous namespace, w
295 MUST_USE_RESULT static Object* CallJsIntrinsic( 308 MUST_USE_RESULT static Object* CallJsIntrinsic(
296 Isolate* isolate, Handle<JSFunction> function, 309 Isolate* isolate, Handle<JSFunction> function,
297 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { 310 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
298 HandleScope handleScope(isolate); 311 HandleScope handleScope(isolate);
299 int argc = args.length() - 1; 312 int argc = args.length() - 1;
300 ScopedVector<Handle<Object> > argv(argc); 313 ScopedVector<Handle<Object> > argv(argc);
301 for (int i = 0; i < argc; ++i) { 314 for (int i = 0; i < argc; ++i) {
302 argv[i] = args.at<Object>(i + 1); 315 argv[i] = args.at<Object>(i + 1);
303 } 316 }
304 Handle<Object> result; 317 Handle<Object> result;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 501
489 // Set the length. 502 // Set the length.
490 array->set_length(Smi::FromInt(new_length)); 503 array->set_length(Smi::FromInt(new_length));
491 return Smi::FromInt(new_length); 504 return Smi::FromInt(new_length);
492 } 505 }
493 506
494 507
495 BUILTIN(ArraySlice) { 508 BUILTIN(ArraySlice) {
496 HandleScope scope(isolate); 509 HandleScope scope(isolate);
497 Handle<Object> receiver = args.receiver(); 510 Handle<Object> receiver = args.receiver();
511 Handle<JSObject> object;
512 Handle<FixedArrayBase> elms_obj;
498 int len = -1; 513 int len = -1;
499 int relative_start = 0; 514 int relative_start = 0;
500 int relative_end = 0; 515 int relative_end = 0;
501 { 516 bool is_sloppy_arguments = false;
517
518 if (receiver->IsJSArray()) {
502 DisallowHeapAllocation no_gc; 519 DisallowHeapAllocation no_gc;
503 if (receiver->IsJSArray()) { 520 JSArray* array = JSArray::cast(*receiver);
504 JSArray* array = JSArray::cast(*receiver); 521 if (!array->HasFastElements() ||
505 if (!IsJSArrayFastElementMovingAllowed(isolate, array)) { 522 !IsJSArrayFastElementMovingAllowed(isolate, array)) {
523 AllowHeapAllocation allow_allocation;
524 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
525 }
526 len = Smi::cast(array->length())->value();
527 object = Handle<JSObject>::cast(receiver);
528 elms_obj = handle(array->elements(), isolate);
529 } else if (receiver->IsJSObject() &&
530 GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver),
531 &len)) {
532 // Array.prototype.slice(arguments, ...) is quite a common idiom
533 // (notably more than 50% of invocations in Web apps).
534 // Treat it in C++ as well.
535 is_sloppy_arguments = true;
536 object = Handle<JSObject>::cast(receiver);
537 elms_obj = handle(object->elements(), isolate);
538 } else {
539 AllowHeapAllocation allow_allocation;
540 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
541 }
542 DCHECK(len >= 0);
543 int argument_count = args.length() - 1;
544 // Note carefully chosen defaults---if argument is missing,
545 // it's undefined which gets converted to 0 for relative_start
546 // and to len for relative_end.
547 relative_start = 0;
548 relative_end = len;
549 if (argument_count > 0) {
550 DisallowHeapAllocation no_gc;
551 if (!ClampedToInteger(args[1], &relative_start)) {
Igor Sheludko 2015/08/31 10:42:51 I think clamping could be wrong if we ever have a
Camillo Bruni 2015/08/31 11:10:08 I agree that the name ClampedToInteger is not a go
552 AllowHeapAllocation allow_allocation;
553 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
554 }
555 if (argument_count > 1) {
556 Object* end_arg = args[2];
557 // slice handles the end_arg specially
558 if (end_arg->IsUndefined()) {
559 relative_end = len;
560 } else if (!ClampedToInteger(end_arg, &relative_end)) {
506 AllowHeapAllocation allow_allocation; 561 AllowHeapAllocation allow_allocation;
507 return CallJsIntrinsic(isolate, isolate->array_slice(), args); 562 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
508 } 563 }
509
510 if (!array->HasFastElements()) {
511 AllowHeapAllocation allow_allocation;
512 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
513 }
514
515 len = Smi::cast(array->length())->value();
516 } else {
517 // Array.slice(arguments, ...) is quite a common idiom (notably more
518 // than 50% of invocations in Web apps). Treat it in C++ as well.
519 Map* arguments_map =
520 isolate->context()->native_context()->sloppy_arguments_map();
521
522 bool is_arguments_object_with_fast_elements =
523 receiver->IsJSObject() &&
524 JSObject::cast(*receiver)->map() == arguments_map;
525 if (!is_arguments_object_with_fast_elements) {
526 AllowHeapAllocation allow_allocation;
527 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
528 }
529 JSObject* object = JSObject::cast(*receiver);
530
531 if (!object->HasFastElements()) {
532 AllowHeapAllocation allow_allocation;
533 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
534 }
535
536 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
537 if (!len_obj->IsSmi()) {
538 AllowHeapAllocation allow_allocation;
539 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
540 }
541 len = Smi::cast(len_obj)->value();
542 if (len > object->elements()->length()) {
543 AllowHeapAllocation allow_allocation;
544 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
545 }
546 }
547
548 DCHECK(len >= 0);
549 int n_arguments = args.length() - 1;
550
551 // Note carefully choosen defaults---if argument is missing,
552 // it's undefined which gets converted to 0 for relative_start
553 // and to len for relative_end.
554 relative_start = 0;
555 relative_end = len;
556 if (n_arguments > 0) {
557 Object* arg1 = args[1];
558 if (arg1->IsSmi()) {
559 relative_start = Smi::cast(arg1)->value();
560 } else if (arg1->IsHeapNumber()) {
561 double start = HeapNumber::cast(arg1)->value();
562 if (start < kMinInt || start > kMaxInt) {
563 AllowHeapAllocation allow_allocation;
564 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
565 }
566 relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
567 } else if (!arg1->IsUndefined()) {
568 AllowHeapAllocation allow_allocation;
569 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
570 }
571 if (n_arguments > 1) {
572 Object* arg2 = args[2];
573 if (arg2->IsSmi()) {
574 relative_end = Smi::cast(arg2)->value();
575 } else if (arg2->IsHeapNumber()) {
576 double end = HeapNumber::cast(arg2)->value();
577 if (end < kMinInt || end > kMaxInt) {
578 AllowHeapAllocation allow_allocation;
579 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
580 }
581 relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
582 } else if (!arg2->IsUndefined()) {
583 AllowHeapAllocation allow_allocation;
584 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
585 }
586 }
587 } 564 }
588 } 565 }
589 566
590 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. 567 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
591 int k = (relative_start < 0) ? Max(len + relative_start, 0) 568 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
592 : Min(relative_start, len); 569 : Min(relative_start, len);
593 570
594 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. 571 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
595 int final = (relative_end < 0) ? Max(len + relative_end, 0) 572 uint32_t actual_end =
596 : Min(relative_end, len); 573 (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
597
598 // Calculate the length of result array.
599 int result_len = Max(final - k, 0);
600
601 Handle<JSObject> object = Handle<JSObject>::cast(receiver);
602 Handle<FixedArrayBase> elms(object->elements(), isolate);
603
604 ElementsKind kind = object->GetElementsKind();
605 if (IsHoleyElementsKind(kind)) {
606 DisallowHeapAllocation no_gc;
607 bool packed = true;
608 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
609 for (int i = k; i < final; i++) {
610 if (!accessor->HasElement(object, i, elms)) {
611 packed = false;
612 break;
613 }
614 }
615 if (packed) {
616 kind = GetPackedElementsKind(kind);
617 } else if (!receiver->IsJSArray()) {
618 AllowHeapAllocation allow_allocation;
619 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
620 }
621 }
622
623 Handle<JSArray> result_array =
624 isolate->factory()->NewJSArray(kind, result_len, result_len);
625
626 DisallowHeapAllocation no_gc;
627 if (result_len == 0) return *result_array;
628 574
629 ElementsAccessor* accessor = object->GetElementsAccessor(); 575 ElementsAccessor* accessor = object->GetElementsAccessor();
630 accessor->CopyElements( 576 if (is_sloppy_arguments &&
631 elms, k, kind, handle(result_array->elements(), isolate), 0, result_len); 577 !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) {
578 // Don't deal with arguments with holes in C++
579 AllowHeapAllocation allow_allocation;
580 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
581 }
582 Handle<JSArray> result_array =
583 accessor->Slice(object, elms_obj, actual_start, actual_end);
632 return *result_array; 584 return *result_array;
633 } 585 }
634 586
635 587
636 BUILTIN(ArraySplice) { 588 BUILTIN(ArraySplice) {
637 HandleScope scope(isolate); 589 HandleScope scope(isolate);
638 Handle<Object> receiver = args.receiver(); 590 Handle<Object> receiver = args.receiver();
639 MaybeHandle<FixedArrayBase> maybe_elms_obj = 591 MaybeHandle<FixedArrayBase> maybe_elms_obj =
640 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); 592 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
641 Handle<FixedArrayBase> elms_obj; 593 Handle<FixedArrayBase> elms_obj;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 } 632 }
681 633
682 int add_count = (argument_count > 1) ? (argument_count - 2) : 0; 634 int add_count = (argument_count > 1) ? (argument_count - 2) : 0;
683 int new_length = len - actual_delete_count + add_count; 635 int new_length = len - actual_delete_count + add_count;
684 636
685 if (new_length != len && JSArray::HasReadOnlyLength(array)) { 637 if (new_length != len && JSArray::HasReadOnlyLength(array)) {
686 AllowHeapAllocation allow_allocation; 638 AllowHeapAllocation allow_allocation;
687 return CallJsIntrinsic(isolate, isolate->array_splice(), args); 639 return CallJsIntrinsic(isolate, isolate->array_splice(), args);
688 } 640 }
689 ElementsAccessor* accessor = array->GetElementsAccessor(); 641 ElementsAccessor* accessor = array->GetElementsAccessor();
690 Handle<JSArray> result = accessor->Splice( 642 Handle<JSArray> result_array = accessor->Splice(
691 array, elms_obj, actual_start, actual_delete_count, args, add_count); 643 array, elms_obj, actual_start, actual_delete_count, args, add_count);
692 return *result; 644 return *result_array;
693 } 645 }
694 646
695 647
696 BUILTIN(ArrayConcat) { 648 BUILTIN(ArrayConcat) {
697 HandleScope scope(isolate); 649 HandleScope scope(isolate);
698 650
699 int n_arguments = args.length(); 651 int n_arguments = args.length();
700 int result_len = 0; 652 int result_len = 0;
701 ElementsKind elements_kind = GetInitialFastElementsKind(); 653 ElementsKind elements_kind = GetInitialFastElementsKind();
702 bool has_double = false; 654 bool has_double = false;
703 { 655 {
704 DisallowHeapAllocation no_gc; 656 DisallowHeapAllocation no_gc;
705 Context* native_context = isolate->context()->native_context(); 657 Context* native_context = isolate->context()->native_context();
706 Object* array_proto = native_context->array_function()->prototype(); 658 Object* array_proto = native_context->array_function()->prototype();
707 PrototypeIterator iter(isolate, array_proto, 659 PrototypeIterator iter(isolate, array_proto,
708 PrototypeIterator::START_AT_RECEIVER); 660 PrototypeIterator::START_AT_RECEIVER);
709 if (!ArrayPrototypeHasNoElements(&iter)) { 661 if (!PrototypeHasNoElements(&iter)) {
710 AllowHeapAllocation allow_allocation; 662 AllowHeapAllocation allow_allocation;
711 return CallJsIntrinsic(isolate, isolate->array_concat(), args); 663 return CallJsIntrinsic(isolate, isolate->array_concat(), args);
712 } 664 }
713 665
714 // Iterate through all the arguments performing checks 666 // Iterate through all the arguments performing checks
715 // and calculating total length. 667 // and calculating total length.
716 bool is_holey = false; 668 bool is_holey = false;
717 for (int i = 0; i < n_arguments; i++) { 669 for (int i = 0; i < n_arguments; i++) {
718 Object* arg = args[i]; 670 Object* arg = args[i];
719 PrototypeIterator iter(isolate, arg); 671 PrototypeIterator iter(isolate, arg);
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1341 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1390 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1342 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1391 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1343 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1392 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1344 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1393 #undef DEFINE_BUILTIN_ACCESSOR_C 1345 #undef DEFINE_BUILTIN_ACCESSOR_C
1394 #undef DEFINE_BUILTIN_ACCESSOR_A 1346 #undef DEFINE_BUILTIN_ACCESSOR_A
1395 1347
1396 1348
1397 } // namespace internal 1349 } // namespace internal
1398 } // namespace v8 1350 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/elements.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698