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-arguments.h" | 7 #include "src/api-arguments.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ | 177 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \ |
178 isolate->factory()->NewStringFromAsciiChecked(method), \ | 178 isolate->factory()->NewStringFromAsciiChecked(method), \ |
179 args.receiver())); \ | 179 args.receiver())); \ |
180 } \ | 180 } \ |
181 Handle<Type> name = Handle<Type>::cast(args.receiver()) | 181 Handle<Type> name = Handle<Type>::cast(args.receiver()) |
182 | 182 |
183 // Throws a TypeError for {method} if the receiver is not coercible to Object, | 183 // Throws a TypeError for {method} if the receiver is not coercible to Object, |
184 // or converts the receiver to a String otherwise and assigns it to a new var | 184 // or converts the receiver to a String otherwise and assigns it to a new var |
185 // with the given {name}. | 185 // with the given {name}. |
186 #define TO_THIS_STRING(name, method) \ | 186 #define TO_THIS_STRING(name, method) \ |
187 if (args.receiver()->IsNull() || args.receiver()->IsUndefined()) { \ | 187 if (args.receiver()->IsNull() || args.receiver()->IsUndefined(isolate)) { \ |
188 THROW_NEW_ERROR_RETURN_FAILURE( \ | 188 THROW_NEW_ERROR_RETURN_FAILURE( \ |
189 isolate, \ | 189 isolate, \ |
190 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ | 190 NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \ |
191 isolate->factory()->NewStringFromAsciiChecked(method))); \ | 191 isolate->factory()->NewStringFromAsciiChecked(method))); \ |
192 } \ | 192 } \ |
193 Handle<String> name; \ | 193 Handle<String> name; \ |
194 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ | 194 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ |
195 isolate, name, Object::ToString(isolate, args.receiver())) | 195 isolate, name, Object::ToString(isolate, args.receiver())) |
196 | 196 |
197 inline bool ClampedToInteger(Object* object, int* out) { | 197 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { |
198 // This is an extended version of ECMA-262 7.1.11 handling signed values | 198 // This is an extended version of ECMA-262 7.1.11 handling signed values |
199 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] | 199 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] |
200 if (object->IsSmi()) { | 200 if (object->IsSmi()) { |
201 *out = Smi::cast(object)->value(); | 201 *out = Smi::cast(object)->value(); |
202 return true; | 202 return true; |
203 } else if (object->IsHeapNumber()) { | 203 } else if (object->IsHeapNumber()) { |
204 double value = HeapNumber::cast(object)->value(); | 204 double value = HeapNumber::cast(object)->value(); |
205 if (std::isnan(value)) { | 205 if (std::isnan(value)) { |
206 *out = 0; | 206 *out = 0; |
207 } else if (value > kMaxInt) { | 207 } else if (value > kMaxInt) { |
208 *out = kMaxInt; | 208 *out = kMaxInt; |
209 } else if (value < kMinInt) { | 209 } else if (value < kMinInt) { |
210 *out = kMinInt; | 210 *out = kMinInt; |
211 } else { | 211 } else { |
212 *out = static_cast<int>(value); | 212 *out = static_cast<int>(value); |
213 } | 213 } |
214 return true; | 214 return true; |
215 } else if (object->IsUndefined() || object->IsNull()) { | 215 } else if (object->IsUndefined(isolate) || object->IsNull()) { |
216 *out = 0; | 216 *out = 0; |
217 return true; | 217 return true; |
218 } else if (object->IsBoolean()) { | 218 } else if (object->IsBoolean()) { |
219 *out = object->IsTrue(); | 219 *out = object->IsTrue(); |
220 return true; | 220 return true; |
221 } | 221 } |
222 return false; | 222 return false; |
223 } | 223 } |
224 | 224 |
225 | 225 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 } | 590 } |
591 DCHECK_LE(0, len); | 591 DCHECK_LE(0, len); |
592 int argument_count = args.length() - 1; | 592 int argument_count = args.length() - 1; |
593 // Note carefully chosen defaults---if argument is missing, | 593 // Note carefully chosen defaults---if argument is missing, |
594 // it's undefined which gets converted to 0 for relative_start | 594 // it's undefined which gets converted to 0 for relative_start |
595 // and to len for relative_end. | 595 // and to len for relative_end. |
596 relative_start = 0; | 596 relative_start = 0; |
597 relative_end = len; | 597 relative_end = len; |
598 if (argument_count > 0) { | 598 if (argument_count > 0) { |
599 DisallowHeapAllocation no_gc; | 599 DisallowHeapAllocation no_gc; |
600 if (!ClampedToInteger(args[1], &relative_start)) { | 600 if (!ClampedToInteger(isolate, args[1], &relative_start)) { |
601 AllowHeapAllocation allow_allocation; | 601 AllowHeapAllocation allow_allocation; |
602 return CallJsIntrinsic(isolate, isolate->array_slice(), args); | 602 return CallJsIntrinsic(isolate, isolate->array_slice(), args); |
603 } | 603 } |
604 if (argument_count > 1) { | 604 if (argument_count > 1) { |
605 Object* end_arg = args[2]; | 605 Object* end_arg = args[2]; |
606 // slice handles the end_arg specially | 606 // slice handles the end_arg specially |
607 if (end_arg->IsUndefined()) { | 607 if (end_arg->IsUndefined(isolate)) { |
608 relative_end = len; | 608 relative_end = len; |
609 } else if (!ClampedToInteger(end_arg, &relative_end)) { | 609 } else if (!ClampedToInteger(isolate, end_arg, &relative_end)) { |
610 AllowHeapAllocation allow_allocation; | 610 AllowHeapAllocation allow_allocation; |
611 return CallJsIntrinsic(isolate, isolate->array_slice(), args); | 611 return CallJsIntrinsic(isolate, isolate->array_slice(), args); |
612 } | 612 } |
613 } | 613 } |
614 } | 614 } |
615 | 615 |
616 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. | 616 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. |
617 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 617 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
618 : Min(relative_start, len); | 618 : Min(relative_start, len); |
619 | 619 |
(...skipping 17 matching lines...) Expand all Loading... |
637 // If anything with @@species has been messed with, call out to JS. | 637 // If anything with @@species has been messed with, call out to JS. |
638 !isolate->IsArraySpeciesLookupChainIntact())) { | 638 !isolate->IsArraySpeciesLookupChainIntact())) { |
639 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 639 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
640 } | 640 } |
641 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 641 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
642 | 642 |
643 int argument_count = args.length() - 1; | 643 int argument_count = args.length() - 1; |
644 int relative_start = 0; | 644 int relative_start = 0; |
645 if (argument_count > 0) { | 645 if (argument_count > 0) { |
646 DisallowHeapAllocation no_gc; | 646 DisallowHeapAllocation no_gc; |
647 if (!ClampedToInteger(args[1], &relative_start)) { | 647 if (!ClampedToInteger(isolate, args[1], &relative_start)) { |
648 AllowHeapAllocation allow_allocation; | 648 AllowHeapAllocation allow_allocation; |
649 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 649 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
650 } | 650 } |
651 } | 651 } |
652 int len = Smi::cast(array->length())->value(); | 652 int len = Smi::cast(array->length())->value(); |
653 // clip relative start to [0, len] | 653 // clip relative start to [0, len] |
654 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 654 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
655 : Min(relative_start, len); | 655 : Min(relative_start, len); |
656 | 656 |
657 int actual_delete_count; | 657 int actual_delete_count; |
658 if (argument_count == 1) { | 658 if (argument_count == 1) { |
659 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is | 659 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is |
660 // given as a request to delete all the elements from the start. | 660 // given as a request to delete all the elements from the start. |
661 // And it differs from the case of undefined delete count. | 661 // And it differs from the case of undefined delete count. |
662 // This does not follow ECMA-262, but we do the same for compatibility. | 662 // This does not follow ECMA-262, but we do the same for compatibility. |
663 DCHECK(len - actual_start >= 0); | 663 DCHECK(len - actual_start >= 0); |
664 actual_delete_count = len - actual_start; | 664 actual_delete_count = len - actual_start; |
665 } else { | 665 } else { |
666 int delete_count = 0; | 666 int delete_count = 0; |
667 DisallowHeapAllocation no_gc; | 667 DisallowHeapAllocation no_gc; |
668 if (argument_count > 1) { | 668 if (argument_count > 1) { |
669 if (!ClampedToInteger(args[2], &delete_count)) { | 669 if (!ClampedToInteger(isolate, args[2], &delete_count)) { |
670 AllowHeapAllocation allow_allocation; | 670 AllowHeapAllocation allow_allocation; |
671 return CallJsIntrinsic(isolate, isolate->array_splice(), args); | 671 return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
672 } | 672 } |
673 } | 673 } |
674 actual_delete_count = Min(Max(delete_count, 0), len - actual_start); | 674 actual_delete_count = Min(Max(delete_count, 0), len - actual_start); |
675 } | 675 } |
676 | 676 |
677 int add_count = (argument_count > 1) ? (argument_count - 2) : 0; | 677 int add_count = (argument_count > 1) ? (argument_count - 2) : 0; |
678 int new_length = len - actual_delete_count + add_count; | 678 int new_length = len - actual_delete_count + add_count; |
679 | 679 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 // Convert storage to dictionary mode. | 812 // Convert storage to dictionary mode. |
813 void SetDictionaryMode() { | 813 void SetDictionaryMode() { |
814 DCHECK(fast_elements() && is_fixed_array()); | 814 DCHECK(fast_elements() && is_fixed_array()); |
815 Handle<FixedArray> current_storage = storage_fixed_array(); | 815 Handle<FixedArray> current_storage = storage_fixed_array(); |
816 Handle<SeededNumberDictionary> slow_storage( | 816 Handle<SeededNumberDictionary> slow_storage( |
817 SeededNumberDictionary::New(isolate_, current_storage->length())); | 817 SeededNumberDictionary::New(isolate_, current_storage->length())); |
818 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); | 818 uint32_t current_length = static_cast<uint32_t>(current_storage->length()); |
819 FOR_WITH_HANDLE_SCOPE( | 819 FOR_WITH_HANDLE_SCOPE( |
820 isolate_, uint32_t, i = 0, i, i < current_length, i++, { | 820 isolate_, uint32_t, i = 0, i, i < current_length, i++, { |
821 Handle<Object> element(current_storage->get(i), isolate_); | 821 Handle<Object> element(current_storage->get(i), isolate_); |
822 if (!element->IsTheHole()) { | 822 if (!element->IsTheHole(isolate_)) { |
823 // The object holding this backing store has just been allocated, so | 823 // The object holding this backing store has just been allocated, so |
824 // it cannot yet be used as a prototype. | 824 // it cannot yet be used as a prototype. |
825 Handle<SeededNumberDictionary> new_storage = | 825 Handle<SeededNumberDictionary> new_storage = |
826 SeededNumberDictionary::AtNumberPut(slow_storage, i, element, | 826 SeededNumberDictionary::AtNumberPut(slow_storage, i, element, |
827 false); | 827 false); |
828 if (!new_storage.is_identical_to(slow_storage)) { | 828 if (!new_storage.is_identical_to(slow_storage)) { |
829 slow_storage = loop_scope.CloseAndEscape(new_storage); | 829 slow_storage = loop_scope.CloseAndEscape(new_storage); |
830 } | 830 } |
831 } | 831 } |
832 }); | 832 }); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 int element_count = 0; | 869 int element_count = 0; |
870 switch (array->GetElementsKind()) { | 870 switch (array->GetElementsKind()) { |
871 case FAST_SMI_ELEMENTS: | 871 case FAST_SMI_ELEMENTS: |
872 case FAST_HOLEY_SMI_ELEMENTS: | 872 case FAST_HOLEY_SMI_ELEMENTS: |
873 case FAST_ELEMENTS: | 873 case FAST_ELEMENTS: |
874 case FAST_HOLEY_ELEMENTS: { | 874 case FAST_HOLEY_ELEMENTS: { |
875 // Fast elements can't have lengths that are not representable by | 875 // Fast elements can't have lengths that are not representable by |
876 // a 32-bit signed integer. | 876 // a 32-bit signed integer. |
877 DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); | 877 DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); |
878 int fast_length = static_cast<int>(length); | 878 int fast_length = static_cast<int>(length); |
879 Handle<FixedArray> elements(FixedArray::cast(array->elements())); | 879 Isolate* isolate = array->GetIsolate(); |
| 880 Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate); |
880 for (int i = 0; i < fast_length; i++) { | 881 for (int i = 0; i < fast_length; i++) { |
881 if (!elements->get(i)->IsTheHole()) element_count++; | 882 if (!elements->get(i)->IsTheHole(isolate)) element_count++; |
882 } | 883 } |
883 break; | 884 break; |
884 } | 885 } |
885 case FAST_DOUBLE_ELEMENTS: | 886 case FAST_DOUBLE_ELEMENTS: |
886 case FAST_HOLEY_DOUBLE_ELEMENTS: { | 887 case FAST_HOLEY_DOUBLE_ELEMENTS: { |
887 // Fast elements can't have lengths that are not representable by | 888 // Fast elements can't have lengths that are not representable by |
888 // a 32-bit signed integer. | 889 // a 32-bit signed integer. |
889 DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0); | 890 DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0); |
890 int fast_length = static_cast<int>(length); | 891 int fast_length = static_cast<int>(length); |
891 if (array->elements()->IsFixedArray()) { | 892 if (array->elements()->IsFixedArray()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 switch (kind) { | 948 switch (kind) { |
948 case FAST_SMI_ELEMENTS: | 949 case FAST_SMI_ELEMENTS: |
949 case FAST_ELEMENTS: | 950 case FAST_ELEMENTS: |
950 case FAST_HOLEY_SMI_ELEMENTS: | 951 case FAST_HOLEY_SMI_ELEMENTS: |
951 case FAST_HOLEY_ELEMENTS: { | 952 case FAST_HOLEY_ELEMENTS: { |
952 DisallowHeapAllocation no_gc; | 953 DisallowHeapAllocation no_gc; |
953 FixedArray* elements = FixedArray::cast(object->elements()); | 954 FixedArray* elements = FixedArray::cast(object->elements()); |
954 uint32_t length = static_cast<uint32_t>(elements->length()); | 955 uint32_t length = static_cast<uint32_t>(elements->length()); |
955 if (range < length) length = range; | 956 if (range < length) length = range; |
956 for (uint32_t i = 0; i < length; i++) { | 957 for (uint32_t i = 0; i < length; i++) { |
957 if (!elements->get(i)->IsTheHole()) { | 958 if (!elements->get(i)->IsTheHole(isolate)) { |
958 indices->Add(i); | 959 indices->Add(i); |
959 } | 960 } |
960 } | 961 } |
961 break; | 962 break; |
962 } | 963 } |
963 case FAST_HOLEY_DOUBLE_ELEMENTS: | 964 case FAST_HOLEY_DOUBLE_ELEMENTS: |
964 case FAST_DOUBLE_ELEMENTS: { | 965 case FAST_DOUBLE_ELEMENTS: { |
965 if (object->elements()->IsFixedArray()) { | 966 if (object->elements()->IsFixedArray()) { |
966 DCHECK(object->elements()->length() == 0); | 967 DCHECK(object->elements()->length() == 0); |
967 break; | 968 break; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 case FAST_ELEMENTS: | 1118 case FAST_ELEMENTS: |
1118 case FAST_HOLEY_SMI_ELEMENTS: | 1119 case FAST_HOLEY_SMI_ELEMENTS: |
1119 case FAST_HOLEY_ELEMENTS: { | 1120 case FAST_HOLEY_ELEMENTS: { |
1120 // Run through the elements FixedArray and use HasElement and GetElement | 1121 // Run through the elements FixedArray and use HasElement and GetElement |
1121 // to check the prototype for missing elements. | 1122 // to check the prototype for missing elements. |
1122 Handle<FixedArray> elements(FixedArray::cast(array->elements())); | 1123 Handle<FixedArray> elements(FixedArray::cast(array->elements())); |
1123 int fast_length = static_cast<int>(length); | 1124 int fast_length = static_cast<int>(length); |
1124 DCHECK(fast_length <= elements->length()); | 1125 DCHECK(fast_length <= elements->length()); |
1125 FOR_WITH_HANDLE_SCOPE(isolate, int, j = 0, j, j < fast_length, j++, { | 1126 FOR_WITH_HANDLE_SCOPE(isolate, int, j = 0, j, j < fast_length, j++, { |
1126 Handle<Object> element_value(elements->get(j), isolate); | 1127 Handle<Object> element_value(elements->get(j), isolate); |
1127 if (!element_value->IsTheHole()) { | 1128 if (!element_value->IsTheHole(isolate)) { |
1128 if (!visitor->visit(j, element_value)) return false; | 1129 if (!visitor->visit(j, element_value)) return false; |
1129 } else { | 1130 } else { |
1130 Maybe<bool> maybe = JSReceiver::HasElement(array, j); | 1131 Maybe<bool> maybe = JSReceiver::HasElement(array, j); |
1131 if (!maybe.IsJust()) return false; | 1132 if (!maybe.IsJust()) return false; |
1132 if (maybe.FromJust()) { | 1133 if (maybe.FromJust()) { |
1133 // Call GetElement on array, not its prototype, or getters won't | 1134 // Call GetElement on array, not its prototype, or getters won't |
1134 // have the correct receiver. | 1135 // have the correct receiver. |
1135 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 1136 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
1136 isolate, element_value, | 1137 isolate, element_value, |
1137 JSReceiver::GetElement(isolate, array, j), false); | 1138 JSReceiver::GetElement(isolate, array, j), false); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) { | 1232 static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) { |
1232 HandleScope handle_scope(isolate); | 1233 HandleScope handle_scope(isolate); |
1233 if (!obj->IsJSReceiver()) return Just(false); | 1234 if (!obj->IsJSReceiver()) return Just(false); |
1234 if (!isolate->IsIsConcatSpreadableLookupChainIntact()) { | 1235 if (!isolate->IsIsConcatSpreadableLookupChainIntact()) { |
1235 // Slow path if @@isConcatSpreadable has been used. | 1236 // Slow path if @@isConcatSpreadable has been used. |
1236 Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol()); | 1237 Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol()); |
1237 Handle<Object> value; | 1238 Handle<Object> value; |
1238 MaybeHandle<Object> maybeValue = | 1239 MaybeHandle<Object> maybeValue = |
1239 i::Runtime::GetObjectProperty(isolate, obj, key); | 1240 i::Runtime::GetObjectProperty(isolate, obj, key); |
1240 if (!maybeValue.ToHandle(&value)) return Nothing<bool>(); | 1241 if (!maybeValue.ToHandle(&value)) return Nothing<bool>(); |
1241 if (!value->IsUndefined()) return Just(value->BooleanValue()); | 1242 if (!value->IsUndefined(isolate)) return Just(value->BooleanValue()); |
1242 } | 1243 } |
1243 return Object::IsArray(obj); | 1244 return Object::IsArray(obj); |
1244 } | 1245 } |
1245 | 1246 |
1246 | 1247 |
1247 Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species, | 1248 Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species, |
1248 Isolate* isolate) { | 1249 Isolate* isolate) { |
1249 int argument_count = args->length(); | 1250 int argument_count = args->length(); |
1250 | 1251 |
1251 bool is_array_species = *species == isolate->context()->array_function(); | 1252 bool is_array_species = *species == isolate->context()->array_function(); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1490 | 1491 |
1491 } // namespace | 1492 } // namespace |
1492 | 1493 |
1493 | 1494 |
1494 // ES6 22.1.3.1 Array.prototype.concat | 1495 // ES6 22.1.3.1 Array.prototype.concat |
1495 BUILTIN(ArrayConcat) { | 1496 BUILTIN(ArrayConcat) { |
1496 HandleScope scope(isolate); | 1497 HandleScope scope(isolate); |
1497 | 1498 |
1498 Handle<Object> receiver = args.receiver(); | 1499 Handle<Object> receiver = args.receiver(); |
1499 // TODO(bmeurer): Do we really care about the exact exception message here? | 1500 // TODO(bmeurer): Do we really care about the exact exception message here? |
1500 if (receiver->IsNull() || receiver->IsUndefined()) { | 1501 if (receiver->IsNull() || receiver->IsUndefined(isolate)) { |
1501 THROW_NEW_ERROR_RETURN_FAILURE( | 1502 THROW_NEW_ERROR_RETURN_FAILURE( |
1502 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, | 1503 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, |
1503 isolate->factory()->NewStringFromAsciiChecked( | 1504 isolate->factory()->NewStringFromAsciiChecked( |
1504 "Array.prototype.concat"))); | 1505 "Array.prototype.concat"))); |
1505 } | 1506 } |
1506 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1507 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1507 isolate, receiver, Object::ToObject(isolate, args.receiver())); | 1508 isolate, receiver, Object::ToObject(isolate, args.receiver())); |
1508 args[0] = *receiver; | 1509 args[0] = *receiver; |
1509 | 1510 |
1510 Handle<JSArray> result_array; | 1511 Handle<JSArray> result_array; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1690 isolate); | 1691 isolate); |
1691 if (map->prototype() != *prototype) { | 1692 if (map->prototype() != *prototype) { |
1692 map = Map::TransitionToPrototype(map, prototype, FAST_PROTOTYPE); | 1693 map = Map::TransitionToPrototype(map, prototype, FAST_PROTOTYPE); |
1693 } | 1694 } |
1694 | 1695 |
1695 // Actually allocate the object. | 1696 // Actually allocate the object. |
1696 Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map); | 1697 Handle<JSObject> object = isolate->factory()->NewJSObjectFromMap(map); |
1697 | 1698 |
1698 // Define the properties if properties was specified and is not undefined. | 1699 // Define the properties if properties was specified and is not undefined. |
1699 Handle<Object> properties = args.atOrUndefined(isolate, 2); | 1700 Handle<Object> properties = args.atOrUndefined(isolate, 2); |
1700 if (!properties->IsUndefined()) { | 1701 if (!properties->IsUndefined(isolate)) { |
1701 RETURN_FAILURE_ON_EXCEPTION( | 1702 RETURN_FAILURE_ON_EXCEPTION( |
1702 isolate, JSReceiver::DefineProperties(isolate, object, properties)); | 1703 isolate, JSReceiver::DefineProperties(isolate, object, properties)); |
1703 } | 1704 } |
1704 | 1705 |
1705 return *object; | 1706 return *object; |
1706 } | 1707 } |
1707 | 1708 |
1708 // ES6 section 19.1.2.3 Object.defineProperties | 1709 // ES6 section 19.1.2.3 Object.defineProperties |
1709 BUILTIN(ObjectDefineProperties) { | 1710 BUILTIN(ObjectDefineProperties) { |
1710 HandleScope scope(isolate); | 1711 HandleScope scope(isolate); |
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2979 // 3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a | 2980 // 3. If buffer does not have an [[ArrayBufferData]] internal slot, throw a |
2980 // TypeError exception. | 2981 // TypeError exception. |
2981 if (!buffer->IsJSArrayBuffer()) { | 2982 if (!buffer->IsJSArrayBuffer()) { |
2982 THROW_NEW_ERROR_RETURN_FAILURE( | 2983 THROW_NEW_ERROR_RETURN_FAILURE( |
2983 isolate, NewTypeError(MessageTemplate::kDataViewNotArrayBuffer)); | 2984 isolate, NewTypeError(MessageTemplate::kDataViewNotArrayBuffer)); |
2984 } | 2985 } |
2985 Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(buffer); | 2986 Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(buffer); |
2986 | 2987 |
2987 // 4. Let numberOffset be ? ToNumber(byteOffset). | 2988 // 4. Let numberOffset be ? ToNumber(byteOffset). |
2988 Handle<Object> number_offset; | 2989 Handle<Object> number_offset; |
2989 if (byte_offset->IsUndefined()) { | 2990 if (byte_offset->IsUndefined(isolate)) { |
2990 // We intentionally violate the specification at this point to allow | 2991 // We intentionally violate the specification at this point to allow |
2991 // for new DataView(buffer) invocations to be equivalent to the full | 2992 // for new DataView(buffer) invocations to be equivalent to the full |
2992 // new DataView(buffer, 0) invocation. | 2993 // new DataView(buffer, 0) invocation. |
2993 number_offset = handle(Smi::FromInt(0), isolate); | 2994 number_offset = handle(Smi::FromInt(0), isolate); |
2994 } else { | 2995 } else { |
2995 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_offset, | 2996 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_offset, |
2996 Object::ToNumber(byte_offset)); | 2997 Object::ToNumber(byte_offset)); |
2997 } | 2998 } |
2998 | 2999 |
2999 // 5. Let offset be ToInteger(numberOffset). | 3000 // 5. Let offset be ToInteger(numberOffset). |
(...skipping 14 matching lines...) Expand all Loading... |
3014 // internal slot. | 3015 // internal slot. |
3015 double const buffer_byte_length = array_buffer->byte_length()->Number(); | 3016 double const buffer_byte_length = array_buffer->byte_length()->Number(); |
3016 | 3017 |
3017 // 9. If offset > bufferByteLength, throw a RangeError exception | 3018 // 9. If offset > bufferByteLength, throw a RangeError exception |
3018 if (offset->Number() > buffer_byte_length) { | 3019 if (offset->Number() > buffer_byte_length) { |
3019 THROW_NEW_ERROR_RETURN_FAILURE( | 3020 THROW_NEW_ERROR_RETURN_FAILURE( |
3020 isolate, NewRangeError(MessageTemplate::kInvalidDataViewOffset)); | 3021 isolate, NewRangeError(MessageTemplate::kInvalidDataViewOffset)); |
3021 } | 3022 } |
3022 | 3023 |
3023 Handle<Object> view_byte_length; | 3024 Handle<Object> view_byte_length; |
3024 if (byte_length->IsUndefined()) { | 3025 if (byte_length->IsUndefined(isolate)) { |
3025 // 10. If byteLength is undefined, then | 3026 // 10. If byteLength is undefined, then |
3026 // a. Let viewByteLength be bufferByteLength - offset. | 3027 // a. Let viewByteLength be bufferByteLength - offset. |
3027 view_byte_length = | 3028 view_byte_length = |
3028 isolate->factory()->NewNumber(buffer_byte_length - offset->Number()); | 3029 isolate->factory()->NewNumber(buffer_byte_length - offset->Number()); |
3029 } else { | 3030 } else { |
3030 // 11. Else, | 3031 // 11. Else, |
3031 // a. Let viewByteLength be ? ToLength(byteLength). | 3032 // a. Let viewByteLength be ? ToLength(byteLength). |
3032 // b. If offset+viewByteLength > bufferByteLength, throw a RangeError | 3033 // b. If offset+viewByteLength > bufferByteLength, throw a RangeError |
3033 // exception | 3034 // exception |
3034 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 3035 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4198 function->shared()->set_name_should_print_as_anonymous(true); | 4199 function->shared()->set_name_should_print_as_anonymous(true); |
4199 } | 4200 } |
4200 | 4201 |
4201 // If new.target is equal to target then the function created | 4202 // If new.target is equal to target then the function created |
4202 // is already correctly setup and nothing else should be done | 4203 // is already correctly setup and nothing else should be done |
4203 // here. But if new.target is not equal to target then we are | 4204 // here. But if new.target is not equal to target then we are |
4204 // have a Function builtin subclassing case and therefore the | 4205 // have a Function builtin subclassing case and therefore the |
4205 // function has wrong initial map. To fix that we create a new | 4206 // function has wrong initial map. To fix that we create a new |
4206 // function object with correct initial map. | 4207 // function object with correct initial map. |
4207 Handle<Object> unchecked_new_target = args.new_target(); | 4208 Handle<Object> unchecked_new_target = args.new_target(); |
4208 if (!unchecked_new_target->IsUndefined() && | 4209 if (!unchecked_new_target->IsUndefined(isolate) && |
4209 !unchecked_new_target.is_identical_to(target)) { | 4210 !unchecked_new_target.is_identical_to(target)) { |
4210 Handle<JSReceiver> new_target = | 4211 Handle<JSReceiver> new_target = |
4211 Handle<JSReceiver>::cast(unchecked_new_target); | 4212 Handle<JSReceiver>::cast(unchecked_new_target); |
4212 Handle<Map> initial_map; | 4213 Handle<Map> initial_map; |
4213 ASSIGN_RETURN_ON_EXCEPTION( | 4214 ASSIGN_RETURN_ON_EXCEPTION( |
4214 isolate, initial_map, | 4215 isolate, initial_map, |
4215 JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction); | 4216 JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction); |
4216 | 4217 |
4217 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); | 4218 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); |
4218 Handle<Map> map = Map::AsLanguageMode( | 4219 Handle<Map> map = Map::AsLanguageMode( |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4350 HandleScope scope(isolate); | 4351 HandleScope scope(isolate); |
4351 RETURN_RESULT_OR_FAILURE( | 4352 RETURN_RESULT_OR_FAILURE( |
4352 isolate, CreateDynamicFunction(isolate, args, "async function")); | 4353 isolate, CreateDynamicFunction(isolate, args, "async function")); |
4353 } | 4354 } |
4354 | 4355 |
4355 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case. | 4356 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case. |
4356 BUILTIN(SymbolConstructor) { | 4357 BUILTIN(SymbolConstructor) { |
4357 HandleScope scope(isolate); | 4358 HandleScope scope(isolate); |
4358 Handle<Symbol> result = isolate->factory()->NewSymbol(); | 4359 Handle<Symbol> result = isolate->factory()->NewSymbol(); |
4359 Handle<Object> description = args.atOrUndefined(isolate, 1); | 4360 Handle<Object> description = args.atOrUndefined(isolate, 1); |
4360 if (!description->IsUndefined()) { | 4361 if (!description->IsUndefined(isolate)) { |
4361 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description, | 4362 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description, |
4362 Object::ToString(isolate, description)); | 4363 Object::ToString(isolate, description)); |
4363 result->set_name(*description); | 4364 result->set_name(*description); |
4364 } | 4365 } |
4365 return *result; | 4366 return *result; |
4366 } | 4367 } |
4367 | 4368 |
4368 | 4369 |
4369 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Construct]] case. | 4370 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Construct]] case. |
4370 BUILTIN(SymbolConstructor_ConstructStub) { | 4371 BUILTIN(SymbolConstructor_ConstructStub) { |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4886 | 4887 |
4887 | 4888 |
4888 namespace { | 4889 namespace { |
4889 | 4890 |
4890 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( | 4891 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( |
4891 Isolate* isolate, | 4892 Isolate* isolate, |
4892 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args) { | 4893 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args) { |
4893 HandleScope scope(isolate); | 4894 HandleScope scope(isolate); |
4894 Handle<HeapObject> function = args.target<HeapObject>(); | 4895 Handle<HeapObject> function = args.target<HeapObject>(); |
4895 Handle<HeapObject> new_target = args.new_target(); | 4896 Handle<HeapObject> new_target = args.new_target(); |
4896 bool is_construct = !new_target->IsUndefined(); | 4897 bool is_construct = !new_target->IsUndefined(isolate); |
4897 Handle<JSReceiver> receiver; | 4898 Handle<JSReceiver> receiver; |
4898 | 4899 |
4899 DCHECK(function->IsFunctionTemplateInfo() || | 4900 DCHECK(function->IsFunctionTemplateInfo() || |
4900 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); | 4901 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); |
4901 | 4902 |
4902 Handle<FunctionTemplateInfo> fun_data = | 4903 Handle<FunctionTemplateInfo> fun_data = |
4903 function->IsFunctionTemplateInfo() | 4904 function->IsFunctionTemplateInfo() |
4904 ? Handle<FunctionTemplateInfo>::cast(function) | 4905 ? Handle<FunctionTemplateInfo>::cast(function) |
4905 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); | 4906 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); |
4906 if (is_construct) { | 4907 if (is_construct) { |
4907 DCHECK(args.receiver()->IsTheHole()); | 4908 DCHECK(args.receiver()->IsTheHole(isolate)); |
4908 if (fun_data->instance_template()->IsUndefined()) { | 4909 if (fun_data->instance_template()->IsUndefined(isolate)) { |
4909 v8::Local<ObjectTemplate> templ = | 4910 v8::Local<ObjectTemplate> templ = |
4910 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), | 4911 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), |
4911 ToApiHandle<v8::FunctionTemplate>(fun_data)); | 4912 ToApiHandle<v8::FunctionTemplate>(fun_data)); |
4912 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); | 4913 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); |
4913 } | 4914 } |
4914 Handle<ObjectTemplateInfo> instance_template( | 4915 Handle<ObjectTemplateInfo> instance_template( |
4915 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); | 4916 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); |
4916 ASSIGN_RETURN_ON_EXCEPTION( | 4917 ASSIGN_RETURN_ON_EXCEPTION( |
4917 isolate, receiver, | 4918 isolate, receiver, |
4918 ApiNatives::InstantiateObject(instance_template, | 4919 ApiNatives::InstantiateObject(instance_template, |
(...skipping 18 matching lines...) Expand all Loading... |
4937 | 4938 |
4938 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); | 4939 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver); |
4939 | 4940 |
4940 if (raw_holder->IsNull()) { | 4941 if (raw_holder->IsNull()) { |
4941 // This function cannot be called with the given receiver. Abort! | 4942 // This function cannot be called with the given receiver. Abort! |
4942 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), | 4943 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation), |
4943 Object); | 4944 Object); |
4944 } | 4945 } |
4945 | 4946 |
4946 Object* raw_call_data = fun_data->call_code(); | 4947 Object* raw_call_data = fun_data->call_code(); |
4947 if (!raw_call_data->IsUndefined()) { | 4948 if (!raw_call_data->IsUndefined(isolate)) { |
4948 DCHECK(raw_call_data->IsCallHandlerInfo()); | 4949 DCHECK(raw_call_data->IsCallHandlerInfo()); |
4949 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 4950 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
4950 Object* callback_obj = call_data->callback(); | 4951 Object* callback_obj = call_data->callback(); |
4951 v8::FunctionCallback callback = | 4952 v8::FunctionCallback callback = |
4952 v8::ToCData<v8::FunctionCallback>(callback_obj); | 4953 v8::ToCData<v8::FunctionCallback>(callback_obj); |
4953 Object* data_obj = call_data->data(); | 4954 Object* data_obj = call_data->data(); |
4954 | 4955 |
4955 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 4956 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
4956 DCHECK(raw_holder->IsJSObject()); | 4957 DCHECK(raw_holder->IsJSObject()); |
4957 | 4958 |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5147 } | 5148 } |
5148 | 5149 |
5149 // Get the invocation callback from the function descriptor that was | 5150 // Get the invocation callback from the function descriptor that was |
5150 // used to create the called object. | 5151 // used to create the called object. |
5151 DCHECK(obj->map()->is_callable()); | 5152 DCHECK(obj->map()->is_callable()); |
5152 JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor()); | 5153 JSFunction* constructor = JSFunction::cast(obj->map()->GetConstructor()); |
5153 // TODO(ishell): turn this back to a DCHECK. | 5154 // TODO(ishell): turn this back to a DCHECK. |
5154 CHECK(constructor->shared()->IsApiFunction()); | 5155 CHECK(constructor->shared()->IsApiFunction()); |
5155 Object* handler = | 5156 Object* handler = |
5156 constructor->shared()->get_api_func_data()->instance_call_handler(); | 5157 constructor->shared()->get_api_func_data()->instance_call_handler(); |
5157 DCHECK(!handler->IsUndefined()); | 5158 DCHECK(!handler->IsUndefined(isolate)); |
5158 // TODO(ishell): remove this debugging code. | 5159 // TODO(ishell): remove this debugging code. |
5159 CHECK(handler->IsCallHandlerInfo()); | 5160 CHECK(handler->IsCallHandlerInfo()); |
5160 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); | 5161 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); |
5161 Object* callback_obj = call_data->callback(); | 5162 Object* callback_obj = call_data->callback(); |
5162 v8::FunctionCallback callback = | 5163 v8::FunctionCallback callback = |
5163 v8::ToCData<v8::FunctionCallback>(callback_obj); | 5164 v8::ToCData<v8::FunctionCallback>(callback_obj); |
5164 | 5165 |
5165 // Get the data for the call and perform the callback. | 5166 // Get the data for the call and perform the callback. |
5166 Object* result; | 5167 Object* result; |
5167 { | 5168 { |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5806 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5807 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
5807 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5808 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
5808 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5809 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
5809 #undef DEFINE_BUILTIN_ACCESSOR_C | 5810 #undef DEFINE_BUILTIN_ACCESSOR_C |
5810 #undef DEFINE_BUILTIN_ACCESSOR_A | 5811 #undef DEFINE_BUILTIN_ACCESSOR_A |
5811 #undef DEFINE_BUILTIN_ACCESSOR_T | 5812 #undef DEFINE_BUILTIN_ACCESSOR_T |
5812 #undef DEFINE_BUILTIN_ACCESSOR_H | 5813 #undef DEFINE_BUILTIN_ACCESSOR_H |
5813 | 5814 |
5814 } // namespace internal | 5815 } // namespace internal |
5815 } // namespace v8 | 5816 } // namespace v8 |
OLD | NEW |