OLD | NEW |
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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 *out = 0; | 188 *out = 0; |
189 return true; | 189 return true; |
190 } else if (object->IsBoolean()) { | 190 } else if (object->IsBoolean()) { |
191 *out = object->IsTrue(); | 191 *out = object->IsTrue(); |
192 return true; | 192 return true; |
193 } | 193 } |
194 return false; | 194 return false; |
195 } | 195 } |
196 | 196 |
197 | 197 |
198 void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, | |
199 FixedDoubleArray* src, int src_index, int len) { | |
200 if (len == 0) return; | |
201 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, | |
202 len * kDoubleSize); | |
203 } | |
204 | |
205 | |
206 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, | 198 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, |
207 int* out) { | 199 int* out) { |
208 Map* arguments_map = | 200 Map* arguments_map = |
209 isolate->context()->native_context()->sloppy_arguments_map(); | 201 isolate->context()->native_context()->sloppy_arguments_map(); |
210 if (object->map() != arguments_map || !object->HasFastElements()) { | 202 if (object->map() != arguments_map || !object->HasFastElements()) { |
211 return false; | 203 return false; |
212 } | 204 } |
213 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); | 205 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); |
214 if (!len_obj->IsSmi()) { | 206 if (!len_obj->IsSmi()) { |
215 return false; | 207 return false; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 417 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
426 DCHECK(!array->map()->is_observed()); | 418 DCHECK(!array->map()->is_observed()); |
427 | 419 |
428 int len = Smi::cast(array->length())->value(); | 420 int len = Smi::cast(array->length())->value(); |
429 if (len == 0) return heap->undefined_value(); | 421 if (len == 0) return heap->undefined_value(); |
430 | 422 |
431 if (JSArray::HasReadOnlyLength(array)) { | 423 if (JSArray::HasReadOnlyLength(array)) { |
432 return CallJsIntrinsic(isolate, isolate->array_shift(), args); | 424 return CallJsIntrinsic(isolate, isolate->array_shift(), args); |
433 } | 425 } |
434 | 426 |
435 // Get first element | 427 Handle<Object> first = array->GetElementsAccessor()->Shift(array, elms_obj); |
436 Handle<Object> first; | |
437 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, first, | |
438 Object::GetElement(isolate, array, 0)); | |
439 | |
440 if (heap->CanMoveObjectStart(*elms_obj)) { | |
441 array->set_elements(heap->LeftTrimFixedArray(*elms_obj, 1)); | |
442 } else { | |
443 // Shift the elements. | |
444 if (elms_obj->IsFixedArray()) { | |
445 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | |
446 DisallowHeapAllocation no_gc; | |
447 heap->MoveElements(*elms, 0, 1, len - 1); | |
448 elms->set(len - 1, heap->the_hole_value()); | |
449 } else { | |
450 Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj); | |
451 MoveDoubleElements(*elms, 0, *elms, 1, len - 1); | |
452 elms->set_the_hole(len - 1); | |
453 } | |
454 } | |
455 | |
456 // Set the length. | |
457 array->set_length(Smi::FromInt(len - 1)); | |
458 | |
459 return *first; | 428 return *first; |
460 } | 429 } |
461 | 430 |
462 | 431 |
463 BUILTIN(ArrayUnshift) { | 432 BUILTIN(ArrayUnshift) { |
464 HandleScope scope(isolate); | 433 HandleScope scope(isolate); |
465 Handle<Object> receiver = args.receiver(); | 434 Handle<Object> receiver = args.receiver(); |
466 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 435 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
467 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); | 436 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); |
468 Handle<FixedArrayBase> elms_obj; | 437 Handle<FixedArrayBase> elms_obj; |
469 if (!maybe_elms_obj.ToHandle(&elms_obj)) { | 438 if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
470 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); | 439 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); |
471 } | 440 } |
472 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 441 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
473 DCHECK(!array->map()->is_observed()); | 442 DCHECK(!array->map()->is_observed()); |
474 int to_add = args.length() - 1; | 443 int to_add = args.length() - 1; |
| 444 if (to_add == 0) { |
| 445 return array->length(); |
| 446 } |
475 // Currently fixed arrays cannot grow too big, so | 447 // Currently fixed arrays cannot grow too big, so |
476 // we should never hit this case. | 448 // we should never hit this case. |
477 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value())); | 449 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value())); |
478 | 450 |
479 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) { | 451 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) { |
480 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); | 452 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); |
481 } | 453 } |
482 | 454 |
483 ElementsAccessor* accessor = array->GetElementsAccessor(); | 455 ElementsAccessor* accessor = array->GetElementsAccessor(); |
484 int new_length = accessor->Unshift(array, elms_obj, &args, to_add); | 456 int new_length = accessor->Unshift(array, elms_obj, &args, to_add); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } | 518 } |
547 | 519 |
548 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. | 520 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. |
549 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 521 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
550 : Min(relative_start, len); | 522 : Min(relative_start, len); |
551 | 523 |
552 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. | 524 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. |
553 uint32_t actual_end = | 525 uint32_t actual_end = |
554 (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len); | 526 (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len); |
555 | 527 |
| 528 if (actual_end <= actual_start) { |
| 529 Handle<JSArray> result_array = |
| 530 isolate->factory()->NewJSArray(GetInitialFastElementsKind(), 0, 0); |
| 531 return *result_array; |
| 532 } |
| 533 |
556 ElementsAccessor* accessor = object->GetElementsAccessor(); | 534 ElementsAccessor* accessor = object->GetElementsAccessor(); |
557 if (is_sloppy_arguments && | 535 if (is_sloppy_arguments && |
558 !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) { | 536 !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) { |
559 // Don't deal with arguments with holes in C++ | 537 // Don't deal with arguments with holes in C++ |
560 AllowHeapAllocation allow_allocation; | 538 AllowHeapAllocation allow_allocation; |
561 return CallJsIntrinsic(isolate, isolate->array_slice(), args); | 539 return CallJsIntrinsic(isolate, isolate->array_slice(), args); |
562 } | 540 } |
563 Handle<JSArray> result_array = | 541 Handle<JSArray> result_array = |
564 accessor->Slice(object, elms_obj, actual_start, actual_end); | 542 accessor->Slice(object, elms_obj, actual_start, actual_end); |
565 return *result_array; | 543 return *result_array; |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1313 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1336 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1314 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1337 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1315 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1338 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1316 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1339 #undef DEFINE_BUILTIN_ACCESSOR_C | 1317 #undef DEFINE_BUILTIN_ACCESSOR_C |
1340 #undef DEFINE_BUILTIN_ACCESSOR_A | 1318 #undef DEFINE_BUILTIN_ACCESSOR_A |
1341 | 1319 |
1342 | 1320 |
1343 } // namespace internal | 1321 } // namespace internal |
1344 } // namespace v8 | 1322 } // namespace v8 |
OLD | NEW |