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

Side by Side Diff: src/runtime/runtime.cc

Issue 598913004: Split more runtime functions into seperate files. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « BUILD.gn ('k') | src/runtime/runtime-collections.cc » ('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 <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 22 matching lines...) Expand all
33 #include "src/parser.h" 33 #include "src/parser.h"
34 #include "src/prototype.h" 34 #include "src/prototype.h"
35 #include "src/runtime/runtime.h" 35 #include "src/runtime/runtime.h"
36 #include "src/runtime/runtime-utils.h" 36 #include "src/runtime/runtime-utils.h"
37 #include "src/runtime-profiler.h" 37 #include "src/runtime-profiler.h"
38 #include "src/scopeinfo.h" 38 #include "src/scopeinfo.h"
39 #include "src/smart-pointers.h" 39 #include "src/smart-pointers.h"
40 #include "src/utils.h" 40 #include "src/utils.h"
41 #include "src/v8threads.h" 41 #include "src/v8threads.h"
42 #include "src/vm-state-inl.h" 42 #include "src/vm-state-inl.h"
43 #include "third_party/fdlibm/fdlibm.h"
44 43
45 44
46 #ifndef _STLP_VENDOR_CSTD
47 // STLPort doesn't import fpclassify and isless into the std namespace.
48 using std::fpclassify;
49 using std::isless;
50 #endif
51
52 namespace v8 { 45 namespace v8 {
53 namespace internal { 46 namespace internal {
54 47
55 // Header of runtime functions. 48 // Header of runtime functions.
56 #define F(name, number_of_args, result_size) \ 49 #define F(name, number_of_args, result_size) \
57 Object* Runtime_##name(int args_length, Object** args_object, \ 50 Object* Runtime_##name(int args_length, Object** args_object, \
58 Isolate* isolate); 51 Isolate* isolate);
59 52
60 #define P(name, number_of_args, result_size) \ 53 #define P(name, number_of_args, result_size) \
61 ObjectPair Runtime_##name(int args_length, Object** args_object, \ 54 ObjectPair Runtime_##name(int args_length, Object** args_object, \
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 633
641 RUNTIME_FUNCTION(Runtime_Fix) { 634 RUNTIME_FUNCTION(Runtime_Fix) {
642 HandleScope scope(isolate); 635 HandleScope scope(isolate);
643 DCHECK(args.length() == 1); 636 DCHECK(args.length() == 1);
644 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); 637 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
645 JSProxy::Fix(proxy); 638 JSProxy::Fix(proxy);
646 return isolate->heap()->undefined_value(); 639 return isolate->heap()->undefined_value();
647 } 640 }
648 641
649 642
650 void Runtime::FreeArrayBuffer(Isolate* isolate,
651 JSArrayBuffer* phantom_array_buffer) {
652 if (phantom_array_buffer->should_be_freed()) {
653 DCHECK(phantom_array_buffer->is_external());
654 free(phantom_array_buffer->backing_store());
655 }
656 if (phantom_array_buffer->is_external()) return;
657
658 size_t allocated_length =
659 NumberToSize(isolate, phantom_array_buffer->byte_length());
660
661 reinterpret_cast<v8::Isolate*>(isolate)
662 ->AdjustAmountOfExternalAllocatedMemory(
663 -static_cast<int64_t>(allocated_length));
664 CHECK(V8::ArrayBufferAllocator() != NULL);
665 V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
666 allocated_length);
667 }
668
669
670 void Runtime::SetupArrayBuffer(Isolate* isolate,
671 Handle<JSArrayBuffer> array_buffer,
672 bool is_external, void* data,
673 size_t allocated_length) {
674 DCHECK(array_buffer->GetInternalFieldCount() ==
675 v8::ArrayBuffer::kInternalFieldCount);
676 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
677 array_buffer->SetInternalField(i, Smi::FromInt(0));
678 }
679 array_buffer->set_backing_store(data);
680 array_buffer->set_flag(Smi::FromInt(0));
681 array_buffer->set_is_external(is_external);
682
683 Handle<Object> byte_length =
684 isolate->factory()->NewNumberFromSize(allocated_length);
685 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
686 array_buffer->set_byte_length(*byte_length);
687
688 array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
689 isolate->heap()->set_array_buffers_list(*array_buffer);
690 array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
691 }
692
693
694 bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
695 Handle<JSArrayBuffer> array_buffer,
696 size_t allocated_length,
697 bool initialize) {
698 void* data;
699 CHECK(V8::ArrayBufferAllocator() != NULL);
700 if (allocated_length != 0) {
701 if (initialize) {
702 data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
703 } else {
704 data =
705 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
706 }
707 if (data == NULL) return false;
708 } else {
709 data = NULL;
710 }
711
712 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
713
714 reinterpret_cast<v8::Isolate*>(isolate)
715 ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
716
717 return true;
718 }
719
720
721 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
722 Isolate* isolate = array_buffer->GetIsolate();
723 for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
724 !view_obj->IsUndefined();) {
725 Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
726 if (view->IsJSTypedArray()) {
727 JSTypedArray::cast(*view)->Neuter();
728 } else if (view->IsJSDataView()) {
729 JSDataView::cast(*view)->Neuter();
730 } else {
731 UNREACHABLE();
732 }
733 view_obj = handle(view->weak_next(), isolate);
734 }
735 array_buffer->Neuter();
736 }
737
738
739 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
740 HandleScope scope(isolate);
741 DCHECK(args.length() == 2);
742 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
743 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
744 if (!holder->byte_length()->IsUndefined()) {
745 // ArrayBuffer is already initialized; probably a fuzz test.
746 return *holder;
747 }
748 size_t allocated_length = 0;
749 if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
750 THROW_NEW_ERROR_RETURN_FAILURE(
751 isolate, NewRangeError("invalid_array_buffer_length",
752 HandleVector<Object>(NULL, 0)));
753 }
754 if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder,
755 allocated_length)) {
756 THROW_NEW_ERROR_RETURN_FAILURE(
757 isolate, NewRangeError("invalid_array_buffer_length",
758 HandleVector<Object>(NULL, 0)));
759 }
760 return *holder;
761 }
762
763
764 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
765 SealHandleScope shs(isolate);
766 DCHECK(args.length() == 1);
767 CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
768 return holder->byte_length();
769 }
770
771
772 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
773 HandleScope scope(isolate);
774 DCHECK(args.length() == 3);
775 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
776 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
777 CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
778 RUNTIME_ASSERT(!source.is_identical_to(target));
779 size_t start = 0;
780 RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
781 size_t target_length = NumberToSize(isolate, target->byte_length());
782
783 if (target_length == 0) return isolate->heap()->undefined_value();
784
785 size_t source_byte_length = NumberToSize(isolate, source->byte_length());
786 RUNTIME_ASSERT(start <= source_byte_length);
787 RUNTIME_ASSERT(source_byte_length - start >= target_length);
788 uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
789 uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
790 CopyBytes(target_data, source_data + start, target_length);
791 return isolate->heap()->undefined_value();
792 }
793
794
795 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
796 HandleScope scope(isolate);
797 DCHECK(args.length() == 1);
798 CONVERT_ARG_CHECKED(Object, object, 0);
799 return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
800 }
801
802
803 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
804 HandleScope scope(isolate);
805 DCHECK(args.length() == 1);
806 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
807 if (array_buffer->backing_store() == NULL) {
808 CHECK(Smi::FromInt(0) == array_buffer->byte_length());
809 return isolate->heap()->undefined_value();
810 }
811 DCHECK(!array_buffer->is_external());
812 void* backing_store = array_buffer->backing_store();
813 size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
814 array_buffer->set_is_external(true);
815 Runtime::NeuterArrayBuffer(array_buffer);
816 V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
817 return isolate->heap()->undefined_value();
818 }
819
820
821 void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
822 ElementsKind* external_elements_kind,
823 ElementsKind* fixed_elements_kind,
824 size_t* element_size) {
825 switch (arrayId) {
826 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size) \
827 case ARRAY_ID_##TYPE: \
828 *array_type = kExternal##Type##Array; \
829 *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
830 *fixed_elements_kind = TYPE##_ELEMENTS; \
831 *element_size = size; \
832 break;
833
834 TYPED_ARRAYS(ARRAY_ID_CASE)
835 #undef ARRAY_ID_CASE
836
837 default:
838 UNREACHABLE();
839 }
840 }
841
842
843 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
844 HandleScope scope(isolate);
845 DCHECK(args.length() == 5);
846 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
847 CONVERT_SMI_ARG_CHECKED(arrayId, 1);
848 CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
849 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
850 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
851
852 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
853 arrayId <= Runtime::ARRAY_ID_LAST);
854
855 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization.
856 size_t element_size = 1; // Bogus initialization.
857 ElementsKind external_elements_kind =
858 EXTERNAL_INT8_ELEMENTS; // Bogus initialization.
859 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization.
860 Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
861 &fixed_elements_kind, &element_size);
862 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
863
864 size_t byte_offset = 0;
865 size_t byte_length = 0;
866 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
867 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
868
869 if (maybe_buffer->IsJSArrayBuffer()) {
870 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
871 size_t array_buffer_byte_length =
872 NumberToSize(isolate, buffer->byte_length());
873 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
874 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
875 } else {
876 RUNTIME_ASSERT(maybe_buffer->IsNull());
877 }
878
879 RUNTIME_ASSERT(byte_length % element_size == 0);
880 size_t length = byte_length / element_size;
881
882 if (length > static_cast<unsigned>(Smi::kMaxValue)) {
883 THROW_NEW_ERROR_RETURN_FAILURE(
884 isolate, NewRangeError("invalid_typed_array_length",
885 HandleVector<Object>(NULL, 0)));
886 }
887
888 // All checks are done, now we can modify objects.
889
890 DCHECK(holder->GetInternalFieldCount() ==
891 v8::ArrayBufferView::kInternalFieldCount);
892 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
893 holder->SetInternalField(i, Smi::FromInt(0));
894 }
895 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
896 holder->set_length(*length_obj);
897 holder->set_byte_offset(*byte_offset_object);
898 holder->set_byte_length(*byte_length_object);
899
900 if (!maybe_buffer->IsNull()) {
901 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
902 holder->set_buffer(*buffer);
903 holder->set_weak_next(buffer->weak_first_view());
904 buffer->set_weak_first_view(*holder);
905
906 Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
907 static_cast<int>(length), array_type,
908 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
909 Handle<Map> map =
910 JSObject::GetElementsTransitionMap(holder, external_elements_kind);
911 JSObject::SetMapAndElements(holder, map, elements);
912 DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
913 } else {
914 holder->set_buffer(Smi::FromInt(0));
915 holder->set_weak_next(isolate->heap()->undefined_value());
916 Handle<FixedTypedArrayBase> elements =
917 isolate->factory()->NewFixedTypedArray(static_cast<int>(length),
918 array_type);
919 holder->set_elements(*elements);
920 }
921 return isolate->heap()->undefined_value();
922 }
923
924
925 // Initializes a typed array from an array-like object.
926 // If an array-like object happens to be a typed array of the same type,
927 // initializes backing store using memove.
928 //
929 // Returns true if backing store was initialized or false otherwise.
930 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
931 HandleScope scope(isolate);
932 DCHECK(args.length() == 4);
933 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
934 CONVERT_SMI_ARG_CHECKED(arrayId, 1);
935 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
936 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
937
938 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
939 arrayId <= Runtime::ARRAY_ID_LAST);
940
941 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization.
942 size_t element_size = 1; // Bogus initialization.
943 ElementsKind external_elements_kind =
944 EXTERNAL_INT8_ELEMENTS; // Bogus intialization.
945 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization.
946 Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
947 &fixed_elements_kind, &element_size);
948
949 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
950
951 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
952 if (source->IsJSTypedArray() &&
953 JSTypedArray::cast(*source)->type() == array_type) {
954 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
955 }
956 size_t length = 0;
957 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
958
959 if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
960 (length > (kMaxInt / element_size))) {
961 THROW_NEW_ERROR_RETURN_FAILURE(
962 isolate, NewRangeError("invalid_typed_array_length",
963 HandleVector<Object>(NULL, 0)));
964 }
965 size_t byte_length = length * element_size;
966
967 DCHECK(holder->GetInternalFieldCount() ==
968 v8::ArrayBufferView::kInternalFieldCount);
969 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
970 holder->SetInternalField(i, Smi::FromInt(0));
971 }
972
973 // NOTE: not initializing backing store.
974 // We assume that the caller of this function will initialize holder
975 // with the loop
976 // for(i = 0; i < length; i++) { holder[i] = source[i]; }
977 // We assume that the caller of this function is always a typed array
978 // constructor.
979 // If source is a typed array, this loop will always run to completion,
980 // so we are sure that the backing store will be initialized.
981 // Otherwise, the indexing operation might throw, so the loop will not
982 // run to completion and the typed array might remain partly initialized.
983 // However we further assume that the caller of this function is a typed array
984 // constructor, and the exception will propagate out of the constructor,
985 // therefore uninitialized memory will not be accessible by a user program.
986 //
987 // TODO(dslomov): revise this once we support subclassing.
988
989 if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length,
990 false)) {
991 THROW_NEW_ERROR_RETURN_FAILURE(
992 isolate, NewRangeError("invalid_array_buffer_length",
993 HandleVector<Object>(NULL, 0)));
994 }
995
996 holder->set_buffer(*buffer);
997 holder->set_byte_offset(Smi::FromInt(0));
998 Handle<Object> byte_length_obj(
999 isolate->factory()->NewNumberFromSize(byte_length));
1000 holder->set_byte_length(*byte_length_obj);
1001 holder->set_length(*length_obj);
1002 holder->set_weak_next(buffer->weak_first_view());
1003 buffer->set_weak_first_view(*holder);
1004
1005 Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
1006 static_cast<int>(length), array_type,
1007 static_cast<uint8_t*>(buffer->backing_store()));
1008 Handle<Map> map =
1009 JSObject::GetElementsTransitionMap(holder, external_elements_kind);
1010 JSObject::SetMapAndElements(holder, map, elements);
1011
1012 if (source->IsJSTypedArray()) {
1013 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
1014
1015 if (typed_array->type() == holder->type()) {
1016 uint8_t* backing_store =
1017 static_cast<uint8_t*>(typed_array->GetBuffer()->backing_store());
1018 size_t source_byte_offset =
1019 NumberToSize(isolate, typed_array->byte_offset());
1020 memcpy(buffer->backing_store(), backing_store + source_byte_offset,
1021 byte_length);
1022 return isolate->heap()->true_value();
1023 }
1024 }
1025
1026 return isolate->heap()->false_value();
1027 }
1028
1029
1030 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
1031 RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \
1032 HandleScope scope(isolate); \
1033 DCHECK(args.length() == 1); \
1034 CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
1035 return holder->accessor(); \
1036 }
1037
1038 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
1039 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
1040 BUFFER_VIEW_GETTER(TypedArray, Length, length)
1041 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
1042
1043 #undef BUFFER_VIEW_GETTER
1044
1045 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
1046 HandleScope scope(isolate);
1047 DCHECK(args.length() == 1);
1048 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1049 return *holder->GetBuffer();
1050 }
1051
1052
1053 // Return codes for Runtime_TypedArraySetFastCases.
1054 // Should be synchronized with typedarray.js natives.
1055 enum TypedArraySetResultCodes {
1056 // Set from typed array of the same type.
1057 // This is processed by TypedArraySetFastCases
1058 TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1059 // Set from typed array of the different type, overlapping in memory.
1060 TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1061 // Set from typed array of the different type, non-overlapping.
1062 TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1063 // Set from non-typed array.
1064 TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1065 };
1066
1067
1068 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
1069 HandleScope scope(isolate);
1070 DCHECK(args.length() == 3);
1071 if (!args[0]->IsJSTypedArray()) {
1072 THROW_NEW_ERROR_RETURN_FAILURE(
1073 isolate,
1074 NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
1075 }
1076
1077 if (!args[1]->IsJSTypedArray())
1078 return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
1079
1080 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
1081 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
1082 CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
1083
1084 Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
1085 Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
1086 size_t offset = 0;
1087 RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
1088 size_t target_length = NumberToSize(isolate, target->length());
1089 size_t source_length = NumberToSize(isolate, source->length());
1090 size_t target_byte_length = NumberToSize(isolate, target->byte_length());
1091 size_t source_byte_length = NumberToSize(isolate, source->byte_length());
1092 if (offset > target_length || offset + source_length > target_length ||
1093 offset + source_length < offset) { // overflow
1094 THROW_NEW_ERROR_RETURN_FAILURE(
1095 isolate, NewRangeError("typed_array_set_source_too_large",
1096 HandleVector<Object>(NULL, 0)));
1097 }
1098
1099 size_t target_offset = NumberToSize(isolate, target->byte_offset());
1100 size_t source_offset = NumberToSize(isolate, source->byte_offset());
1101 uint8_t* target_base =
1102 static_cast<uint8_t*>(target->GetBuffer()->backing_store()) +
1103 target_offset;
1104 uint8_t* source_base =
1105 static_cast<uint8_t*>(source->GetBuffer()->backing_store()) +
1106 source_offset;
1107
1108 // Typed arrays of the same type: use memmove.
1109 if (target->type() == source->type()) {
1110 memmove(target_base + offset * target->element_size(), source_base,
1111 source_byte_length);
1112 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
1113 }
1114
1115 // Typed arrays of different types over the same backing store
1116 if ((source_base <= target_base &&
1117 source_base + source_byte_length > target_base) ||
1118 (target_base <= source_base &&
1119 target_base + target_byte_length > source_base)) {
1120 // We do not support overlapping ArrayBuffers
1121 DCHECK(target->GetBuffer()->backing_store() ==
1122 source->GetBuffer()->backing_store());
1123 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
1124 } else { // Non-overlapping typed arrays
1125 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
1126 }
1127 }
1128
1129
1130 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
1131 DCHECK(args.length() == 0);
1132 DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap +
1133 FixedTypedArrayBase::kDataOffset);
1134 return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
1135 }
1136
1137
1138 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
1139 HandleScope scope(isolate);
1140 DCHECK(args.length() == 4);
1141 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
1142 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
1143 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
1144 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
1145
1146 DCHECK(holder->GetInternalFieldCount() ==
1147 v8::ArrayBufferView::kInternalFieldCount);
1148 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1149 holder->SetInternalField(i, Smi::FromInt(0));
1150 }
1151 size_t buffer_length = 0;
1152 size_t offset = 0;
1153 size_t length = 0;
1154 RUNTIME_ASSERT(
1155 TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
1156 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
1157 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
1158
1159 // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
1160 // Entire range [offset, offset + length] must be in bounds.
1161 RUNTIME_ASSERT(offset <= buffer_length);
1162 RUNTIME_ASSERT(offset + length <= buffer_length);
1163 // No overflow.
1164 RUNTIME_ASSERT(offset + length >= offset);
1165
1166 holder->set_buffer(*buffer);
1167 holder->set_byte_offset(*byte_offset);
1168 holder->set_byte_length(*byte_length);
1169
1170 holder->set_weak_next(buffer->weak_first_view());
1171 buffer->set_weak_first_view(*holder);
1172
1173 return isolate->heap()->undefined_value();
1174 }
1175
1176
1177 inline static bool NeedToFlipBytes(bool is_little_endian) {
1178 #ifdef V8_TARGET_LITTLE_ENDIAN
1179 return !is_little_endian;
1180 #else
1181 return is_little_endian;
1182 #endif
1183 }
1184
1185
1186 template <int n>
1187 inline void CopyBytes(uint8_t* target, uint8_t* source) {
1188 for (int i = 0; i < n; i++) {
1189 *(target++) = *(source++);
1190 }
1191 }
1192
1193
1194 template <int n>
1195 inline void FlipBytes(uint8_t* target, uint8_t* source) {
1196 source = source + (n - 1);
1197 for (int i = 0; i < n; i++) {
1198 *(target++) = *(source--);
1199 }
1200 }
1201
1202
1203 template <typename T>
1204 inline static bool DataViewGetValue(Isolate* isolate,
1205 Handle<JSDataView> data_view,
1206 Handle<Object> byte_offset_obj,
1207 bool is_little_endian, T* result) {
1208 size_t byte_offset = 0;
1209 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1210 return false;
1211 }
1212 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1213
1214 size_t data_view_byte_offset =
1215 NumberToSize(isolate, data_view->byte_offset());
1216 size_t data_view_byte_length =
1217 NumberToSize(isolate, data_view->byte_length());
1218 if (byte_offset + sizeof(T) > data_view_byte_length ||
1219 byte_offset + sizeof(T) < byte_offset) { // overflow
1220 return false;
1221 }
1222
1223 union Value {
1224 T data;
1225 uint8_t bytes[sizeof(T)];
1226 };
1227
1228 Value value;
1229 size_t buffer_offset = data_view_byte_offset + byte_offset;
1230 DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
1231 buffer_offset + sizeof(T));
1232 uint8_t* source =
1233 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1234 if (NeedToFlipBytes(is_little_endian)) {
1235 FlipBytes<sizeof(T)>(value.bytes, source);
1236 } else {
1237 CopyBytes<sizeof(T)>(value.bytes, source);
1238 }
1239 *result = value.data;
1240 return true;
1241 }
1242
1243
1244 template <typename T>
1245 static bool DataViewSetValue(Isolate* isolate, Handle<JSDataView> data_view,
1246 Handle<Object> byte_offset_obj,
1247 bool is_little_endian, T data) {
1248 size_t byte_offset = 0;
1249 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1250 return false;
1251 }
1252 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1253
1254 size_t data_view_byte_offset =
1255 NumberToSize(isolate, data_view->byte_offset());
1256 size_t data_view_byte_length =
1257 NumberToSize(isolate, data_view->byte_length());
1258 if (byte_offset + sizeof(T) > data_view_byte_length ||
1259 byte_offset + sizeof(T) < byte_offset) { // overflow
1260 return false;
1261 }
1262
1263 union Value {
1264 T data;
1265 uint8_t bytes[sizeof(T)];
1266 };
1267
1268 Value value;
1269 value.data = data;
1270 size_t buffer_offset = data_view_byte_offset + byte_offset;
1271 DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
1272 buffer_offset + sizeof(T));
1273 uint8_t* target =
1274 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1275 if (NeedToFlipBytes(is_little_endian)) {
1276 FlipBytes<sizeof(T)>(target, value.bytes);
1277 } else {
1278 CopyBytes<sizeof(T)>(target, value.bytes);
1279 }
1280 return true;
1281 }
1282
1283
1284 #define DATA_VIEW_GETTER(TypeName, Type, Converter) \
1285 RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) { \
1286 HandleScope scope(isolate); \
1287 DCHECK(args.length() == 3); \
1288 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
1289 CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
1290 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \
1291 Type result; \
1292 if (DataViewGetValue(isolate, holder, offset, is_little_endian, \
1293 &result)) { \
1294 return *isolate->factory()->Converter(result); \
1295 } else { \
1296 THROW_NEW_ERROR_RETURN_FAILURE( \
1297 isolate, NewRangeError("invalid_data_view_accessor_offset", \
1298 HandleVector<Object>(NULL, 0))); \
1299 } \
1300 }
1301
1302 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
1303 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
1304 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
1305 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
1306 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
1307 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
1308 DATA_VIEW_GETTER(Float32, float, NewNumber)
1309 DATA_VIEW_GETTER(Float64, double, NewNumber)
1310
1311 #undef DATA_VIEW_GETTER
1312
1313
1314 template <typename T>
1315 static T DataViewConvertValue(double value);
1316
1317
1318 template <>
1319 int8_t DataViewConvertValue<int8_t>(double value) {
1320 return static_cast<int8_t>(DoubleToInt32(value));
1321 }
1322
1323
1324 template <>
1325 int16_t DataViewConvertValue<int16_t>(double value) {
1326 return static_cast<int16_t>(DoubleToInt32(value));
1327 }
1328
1329
1330 template <>
1331 int32_t DataViewConvertValue<int32_t>(double value) {
1332 return DoubleToInt32(value);
1333 }
1334
1335
1336 template <>
1337 uint8_t DataViewConvertValue<uint8_t>(double value) {
1338 return static_cast<uint8_t>(DoubleToUint32(value));
1339 }
1340
1341
1342 template <>
1343 uint16_t DataViewConvertValue<uint16_t>(double value) {
1344 return static_cast<uint16_t>(DoubleToUint32(value));
1345 }
1346
1347
1348 template <>
1349 uint32_t DataViewConvertValue<uint32_t>(double value) {
1350 return DoubleToUint32(value);
1351 }
1352
1353
1354 template <>
1355 float DataViewConvertValue<float>(double value) {
1356 return static_cast<float>(value);
1357 }
1358
1359
1360 template <>
1361 double DataViewConvertValue<double>(double value) {
1362 return value;
1363 }
1364
1365
1366 #define DATA_VIEW_SETTER(TypeName, Type) \
1367 RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) { \
1368 HandleScope scope(isolate); \
1369 DCHECK(args.length() == 4); \
1370 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \
1371 CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \
1372 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); \
1373 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \
1374 Type v = DataViewConvertValue<Type>(value->Number()); \
1375 if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
1376 return isolate->heap()->undefined_value(); \
1377 } else { \
1378 THROW_NEW_ERROR_RETURN_FAILURE( \
1379 isolate, NewRangeError("invalid_data_view_accessor_offset", \
1380 HandleVector<Object>(NULL, 0))); \
1381 } \
1382 }
1383
1384 DATA_VIEW_SETTER(Uint8, uint8_t)
1385 DATA_VIEW_SETTER(Int8, int8_t)
1386 DATA_VIEW_SETTER(Uint16, uint16_t)
1387 DATA_VIEW_SETTER(Int16, int16_t)
1388 DATA_VIEW_SETTER(Uint32, uint32_t)
1389 DATA_VIEW_SETTER(Int32, int32_t)
1390 DATA_VIEW_SETTER(Float32, float)
1391 DATA_VIEW_SETTER(Float64, double)
1392
1393 #undef DATA_VIEW_SETTER
1394
1395
1396 RUNTIME_FUNCTION(Runtime_SetInitialize) {
1397 HandleScope scope(isolate);
1398 DCHECK(args.length() == 1);
1399 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1400 Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
1401 holder->set_table(*table);
1402 return *holder;
1403 }
1404
1405
1406 RUNTIME_FUNCTION(Runtime_SetAdd) {
1407 HandleScope scope(isolate);
1408 DCHECK(args.length() == 2);
1409 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1410 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1411 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1412 table = OrderedHashSet::Add(table, key);
1413 holder->set_table(*table);
1414 return *holder;
1415 }
1416
1417
1418 RUNTIME_FUNCTION(Runtime_SetHas) {
1419 HandleScope scope(isolate);
1420 DCHECK(args.length() == 2);
1421 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1422 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1423 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1424 return isolate->heap()->ToBoolean(table->Contains(key));
1425 }
1426
1427
1428 RUNTIME_FUNCTION(Runtime_SetDelete) {
1429 HandleScope scope(isolate);
1430 DCHECK(args.length() == 2);
1431 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1432 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1433 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1434 bool was_present = false;
1435 table = OrderedHashSet::Remove(table, key, &was_present);
1436 holder->set_table(*table);
1437 return isolate->heap()->ToBoolean(was_present);
1438 }
1439
1440
1441 RUNTIME_FUNCTION(Runtime_SetClear) {
1442 HandleScope scope(isolate);
1443 DCHECK(args.length() == 1);
1444 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1445 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1446 table = OrderedHashSet::Clear(table);
1447 holder->set_table(*table);
1448 return isolate->heap()->undefined_value();
1449 }
1450
1451
1452 RUNTIME_FUNCTION(Runtime_SetGetSize) {
1453 HandleScope scope(isolate);
1454 DCHECK(args.length() == 1);
1455 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1456 Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1457 return Smi::FromInt(table->NumberOfElements());
1458 }
1459
1460
1461 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
1462 HandleScope scope(isolate);
1463 DCHECK(args.length() == 3);
1464 CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1465 CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
1466 CONVERT_SMI_ARG_CHECKED(kind, 2)
1467 RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
1468 kind == JSSetIterator::kKindEntries);
1469 Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
1470 holder->set_table(*table);
1471 holder->set_index(Smi::FromInt(0));
1472 holder->set_kind(Smi::FromInt(kind));
1473 return isolate->heap()->undefined_value();
1474 }
1475
1476
1477 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
1478 SealHandleScope shs(isolate);
1479 DCHECK(args.length() == 2);
1480 CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
1481 CONVERT_ARG_CHECKED(JSArray, value_array, 1);
1482 return holder->Next(value_array);
1483 }
1484
1485
1486 RUNTIME_FUNCTION(Runtime_MapInitialize) {
1487 HandleScope scope(isolate);
1488 DCHECK(args.length() == 1);
1489 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1490 Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
1491 holder->set_table(*table);
1492 return *holder;
1493 }
1494
1495
1496 RUNTIME_FUNCTION(Runtime_MapGet) {
1497 HandleScope scope(isolate);
1498 DCHECK(args.length() == 2);
1499 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1500 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1501 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1502 Handle<Object> lookup(table->Lookup(key), isolate);
1503 return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1504 }
1505
1506
1507 RUNTIME_FUNCTION(Runtime_MapHas) {
1508 HandleScope scope(isolate);
1509 DCHECK(args.length() == 2);
1510 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1511 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1512 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1513 Handle<Object> lookup(table->Lookup(key), isolate);
1514 return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1515 }
1516
1517
1518 RUNTIME_FUNCTION(Runtime_MapDelete) {
1519 HandleScope scope(isolate);
1520 DCHECK(args.length() == 2);
1521 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1522 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1523 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1524 bool was_present = false;
1525 Handle<OrderedHashMap> new_table =
1526 OrderedHashMap::Remove(table, key, &was_present);
1527 holder->set_table(*new_table);
1528 return isolate->heap()->ToBoolean(was_present);
1529 }
1530
1531
1532 RUNTIME_FUNCTION(Runtime_MapClear) {
1533 HandleScope scope(isolate);
1534 DCHECK(args.length() == 1);
1535 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1536 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1537 table = OrderedHashMap::Clear(table);
1538 holder->set_table(*table);
1539 return isolate->heap()->undefined_value();
1540 }
1541
1542
1543 RUNTIME_FUNCTION(Runtime_MapSet) {
1544 HandleScope scope(isolate);
1545 DCHECK(args.length() == 3);
1546 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1547 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1548 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1549 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1550 Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
1551 holder->set_table(*new_table);
1552 return *holder;
1553 }
1554
1555
1556 RUNTIME_FUNCTION(Runtime_MapGetSize) {
1557 HandleScope scope(isolate);
1558 DCHECK(args.length() == 1);
1559 CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1560 Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1561 return Smi::FromInt(table->NumberOfElements());
1562 }
1563
1564
1565 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
1566 HandleScope scope(isolate);
1567 DCHECK(args.length() == 3);
1568 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1569 CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
1570 CONVERT_SMI_ARG_CHECKED(kind, 2)
1571 RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys ||
1572 kind == JSMapIterator::kKindValues ||
1573 kind == JSMapIterator::kKindEntries);
1574 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
1575 holder->set_table(*table);
1576 holder->set_index(Smi::FromInt(0));
1577 holder->set_kind(Smi::FromInt(kind));
1578 return isolate->heap()->undefined_value();
1579 }
1580
1581
1582 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
1583 HandleScope scope(isolate);
1584 DCHECK(args.length() == 1);
1585 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
1586 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1587 Handle<FixedArray> entries =
1588 isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
1589 {
1590 DisallowHeapAllocation no_gc;
1591 int number_of_non_hole_elements = 0;
1592 for (int i = 0; i < table->Capacity(); i++) {
1593 Handle<Object> key(table->KeyAt(i), isolate);
1594 if (table->IsKey(*key)) {
1595 entries->set(number_of_non_hole_elements++, *key);
1596 Object* value = table->Lookup(key);
1597 entries->set(number_of_non_hole_elements++, value);
1598 }
1599 }
1600 DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
1601 }
1602 return *isolate->factory()->NewJSArrayWithElements(entries);
1603 }
1604
1605
1606 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
1607 SealHandleScope shs(isolate);
1608 DCHECK(args.length() == 2);
1609 CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
1610 CONVERT_ARG_CHECKED(JSArray, value_array, 1);
1611 return holder->Next(value_array);
1612 }
1613
1614
1615 static Handle<JSWeakCollection> WeakCollectionInitialize(
1616 Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
1617 DCHECK(weak_collection->map()->inobject_properties() == 0);
1618 Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
1619 weak_collection->set_table(*table);
1620 return weak_collection;
1621 }
1622
1623
1624 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
1625 HandleScope scope(isolate);
1626 DCHECK(args.length() == 1);
1627 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1628 return *WeakCollectionInitialize(isolate, weak_collection);
1629 }
1630
1631
1632 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
1633 HandleScope scope(isolate);
1634 DCHECK(args.length() == 2);
1635 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1636 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1637 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1638 Handle<ObjectHashTable> table(
1639 ObjectHashTable::cast(weak_collection->table()));
1640 RUNTIME_ASSERT(table->IsKey(*key));
1641 Handle<Object> lookup(table->Lookup(key), isolate);
1642 return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1643 }
1644
1645
1646 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
1647 HandleScope scope(isolate);
1648 DCHECK(args.length() == 2);
1649 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1650 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1651 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1652 Handle<ObjectHashTable> table(
1653 ObjectHashTable::cast(weak_collection->table()));
1654 RUNTIME_ASSERT(table->IsKey(*key));
1655 Handle<Object> lookup(table->Lookup(key), isolate);
1656 return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1657 }
1658
1659
1660 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
1661 HandleScope scope(isolate);
1662 DCHECK(args.length() == 2);
1663 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1664 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1665 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1666 Handle<ObjectHashTable> table(
1667 ObjectHashTable::cast(weak_collection->table()));
1668 RUNTIME_ASSERT(table->IsKey(*key));
1669 bool was_present = false;
1670 Handle<ObjectHashTable> new_table =
1671 ObjectHashTable::Remove(table, key, &was_present);
1672 weak_collection->set_table(*new_table);
1673 return isolate->heap()->ToBoolean(was_present);
1674 }
1675
1676
1677 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
1678 HandleScope scope(isolate);
1679 DCHECK(args.length() == 3);
1680 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1681 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1682 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1683 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1684 Handle<ObjectHashTable> table(
1685 ObjectHashTable::cast(weak_collection->table()));
1686 RUNTIME_ASSERT(table->IsKey(*key));
1687 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1688 weak_collection->set_table(*new_table);
1689 return *weak_collection;
1690 }
1691
1692
1693 RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
1694 HandleScope scope(isolate);
1695 DCHECK(args.length() == 1);
1696 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
1697 Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1698 Handle<FixedArray> values =
1699 isolate->factory()->NewFixedArray(table->NumberOfElements());
1700 {
1701 DisallowHeapAllocation no_gc;
1702 int number_of_non_hole_elements = 0;
1703 for (int i = 0; i < table->Capacity(); i++) {
1704 Handle<Object> key(table->KeyAt(i), isolate);
1705 if (table->IsKey(*key)) {
1706 values->set(number_of_non_hole_elements++, *key);
1707 }
1708 }
1709 DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
1710 }
1711 return *isolate->factory()->NewJSArrayWithElements(values);
1712 }
1713
1714
1715 RUNTIME_FUNCTION(Runtime_GetPrototype) { 643 RUNTIME_FUNCTION(Runtime_GetPrototype) {
1716 HandleScope scope(isolate); 644 HandleScope scope(isolate);
1717 DCHECK(args.length() == 1); 645 DCHECK(args.length() == 1);
1718 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); 646 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
1719 // We don't expect access checks to be needed on JSProxy objects. 647 // We don't expect access checks to be needed on JSProxy objects.
1720 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); 648 DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
1721 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); 649 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
1722 do { 650 do {
1723 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && 651 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
1724 !isolate->MayNamedAccess( 652 !isolate->MayNamedAccess(
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2852 // %ObjectFreeze is a fast path and these cases are handled elsewhere. 1780 // %ObjectFreeze is a fast path and these cases are handled elsewhere.
2853 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && 1781 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
2854 !object->map()->is_observed() && !object->IsJSProxy()); 1782 !object->map()->is_observed() && !object->IsJSProxy());
2855 1783
2856 Handle<Object> result; 1784 Handle<Object> result;
2857 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object)); 1785 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
2858 return *result; 1786 return *result;
2859 } 1787 }
2860 1788
2861 1789
2862 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
2863 HandleScope scope(isolate);
2864 DCHECK(args.length() == 2);
2865 CONVERT_SMI_ARG_CHECKED(radix, 1);
2866 RUNTIME_ASSERT(2 <= radix && radix <= 36);
2867
2868 // Fast case where the result is a one character string.
2869 if (args[0]->IsSmi()) {
2870 int value = args.smi_at(0);
2871 if (value >= 0 && value < radix) {
2872 // Character array used for conversion.
2873 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
2874 return *isolate->factory()->LookupSingleCharacterStringFromCode(
2875 kCharTable[value]);
2876 }
2877 }
2878
2879 // Slow case.
2880 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
2881 if (std::isnan(value)) {
2882 return isolate->heap()->nan_string();
2883 }
2884 if (std::isinf(value)) {
2885 if (value < 0) {
2886 return isolate->heap()->minus_infinity_string();
2887 }
2888 return isolate->heap()->infinity_string();
2889 }
2890 char* str = DoubleToRadixCString(value, radix);
2891 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
2892 DeleteArray(str);
2893 return *result;
2894 }
2895
2896
2897 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
2898 HandleScope scope(isolate);
2899 DCHECK(args.length() == 2);
2900
2901 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
2902 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
2903 int f = FastD2IChecked(f_number);
2904 // See DoubleToFixedCString for these constants:
2905 RUNTIME_ASSERT(f >= 0 && f <= 20);
2906 RUNTIME_ASSERT(!Double(value).IsSpecial());
2907 char* str = DoubleToFixedCString(value, f);
2908 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
2909 DeleteArray(str);
2910 return *result;
2911 }
2912
2913
2914 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
2915 HandleScope scope(isolate);
2916 DCHECK(args.length() == 2);
2917
2918 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
2919 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
2920 int f = FastD2IChecked(f_number);
2921 RUNTIME_ASSERT(f >= -1 && f <= 20);
2922 RUNTIME_ASSERT(!Double(value).IsSpecial());
2923 char* str = DoubleToExponentialCString(value, f);
2924 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
2925 DeleteArray(str);
2926 return *result;
2927 }
2928
2929
2930 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
2931 HandleScope scope(isolate);
2932 DCHECK(args.length() == 2);
2933
2934 CONVERT_DOUBLE_ARG_CHECKED(value, 0);
2935 CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
2936 int f = FastD2IChecked(f_number);
2937 RUNTIME_ASSERT(f >= 1 && f <= 21);
2938 RUNTIME_ASSERT(!Double(value).IsSpecial());
2939 char* str = DoubleToPrecisionCString(value, f);
2940 Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
2941 DeleteArray(str);
2942 return *result;
2943 }
2944
2945
2946 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
2947 SealHandleScope shs(isolate);
2948 DCHECK(args.length() == 1);
2949
2950 CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
2951 return isolate->heap()->ToBoolean(Smi::IsValid(number));
2952 }
2953
2954
2955 // Returns a single character string where first character equals 1790 // Returns a single character string where first character equals
2956 // string->Get(index). 1791 // string->Get(index).
2957 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) { 1792 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
2958 if (index < static_cast<uint32_t>(string->length())) { 1793 if (index < static_cast<uint32_t>(string->length())) {
2959 Factory* factory = string->GetIsolate()->factory(); 1794 Factory* factory = string->GetIsolate()->factory();
2960 return factory->LookupSingleCharacterStringFromCode( 1795 return factory->LookupSingleCharacterStringFromCode(
2961 String::Flatten(string)->Get(index)); 1796 String::Flatten(string)->Get(index));
2962 } 1797 }
2963 return Execution::CharAt(string, index); 1798 return Execution::CharAt(string, index);
2964 } 1799 }
(...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after
4368 return isolate->heap()->ToBoolean(value <= 0); 3203 return isolate->heap()->ToBoolean(value <= 0);
4369 case Token::GTE: 3204 case Token::GTE:
4370 return isolate->heap()->ToBoolean(value >= 0); 3205 return isolate->heap()->ToBoolean(value >= 0);
4371 default: 3206 default:
4372 // This should only happen during natives fuzzing. 3207 // This should only happen during natives fuzzing.
4373 return isolate->heap()->undefined_value(); 3208 return isolate->heap()->undefined_value();
4374 } 3209 }
4375 } 3210 }
4376 3211
4377 3212
4378 static bool AreDigits(const uint8_t* s, int from, int to) {
4379 for (int i = from; i < to; i++) {
4380 if (s[i] < '0' || s[i] > '9') return false;
4381 }
4382
4383 return true;
4384 }
4385
4386
4387 static int ParseDecimalInteger(const uint8_t* s, int from, int to) {
4388 DCHECK(to - from < 10); // Overflow is not possible.
4389 DCHECK(from < to);
4390 int d = s[from] - '0';
4391
4392 for (int i = from + 1; i < to; i++) {
4393 d = 10 * d + (s[i] - '0');
4394 }
4395
4396 return d;
4397 }
4398
4399
4400 RUNTIME_FUNCTION(Runtime_StringToNumber) {
4401 HandleScope handle_scope(isolate);
4402 DCHECK(args.length() == 1);
4403 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4404 subject = String::Flatten(subject);
4405
4406 // Fast case: short integer or some sorts of junk values.
4407 if (subject->IsSeqOneByteString()) {
4408 int len = subject->length();
4409 if (len == 0) return Smi::FromInt(0);
4410
4411 DisallowHeapAllocation no_gc;
4412 uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
4413 bool minus = (data[0] == '-');
4414 int start_pos = (minus ? 1 : 0);
4415
4416 if (start_pos == len) {
4417 return isolate->heap()->nan_value();
4418 } else if (data[start_pos] > '9') {
4419 // Fast check for a junk value. A valid string may start from a
4420 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
4421 // or the 'I' character ('Infinity'). All of that have codes not greater
4422 // than '9' except 'I' and &nbsp;.
4423 if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
4424 return isolate->heap()->nan_value();
4425 }
4426 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
4427 // The maximal/minimal smi has 10 digits. If the string has less digits
4428 // we know it will fit into the smi-data type.
4429 int d = ParseDecimalInteger(data, start_pos, len);
4430 if (minus) {
4431 if (d == 0) return isolate->heap()->minus_zero_value();
4432 d = -d;
4433 } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
4434 (len == 1 || data[0] != '0')) {
4435 // String hash is not calculated yet but all the data are present.
4436 // Update the hash field to speed up sequential convertions.
4437 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
4438 #ifdef DEBUG
4439 subject->Hash(); // Force hash calculation.
4440 DCHECK_EQ(static_cast<int>(subject->hash_field()),
4441 static_cast<int>(hash));
4442 #endif
4443 subject->set_hash_field(hash);
4444 }
4445 return Smi::FromInt(d);
4446 }
4447 }
4448
4449 // Slower case.
4450 int flags = ALLOW_HEX;
4451 if (FLAG_harmony_numeric_literals) {
4452 // The current spec draft has not updated "ToNumber Applied to the String
4453 // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
4454 flags |= ALLOW_OCTAL | ALLOW_BINARY;
4455 }
4456
4457 return *isolate->factory()->NewNumber(
4458 StringToDouble(isolate->unicode_cache(), *subject, flags));
4459 }
4460
4461
4462 RUNTIME_FUNCTION(Runtime_StringParseInt) {
4463 HandleScope handle_scope(isolate);
4464 DCHECK(args.length() == 2);
4465 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4466 CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
4467 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
4468
4469 subject = String::Flatten(subject);
4470 double value;
4471
4472 {
4473 DisallowHeapAllocation no_gc;
4474 String::FlatContent flat = subject->GetFlatContent();
4475
4476 // ECMA-262 section 15.1.2.3, empty string is NaN
4477 if (flat.IsOneByte()) {
4478 value =
4479 StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix);
4480 } else {
4481 value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix);
4482 }
4483 }
4484
4485 return *isolate->factory()->NewNumber(value);
4486 }
4487
4488
4489 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
4490 HandleScope shs(isolate);
4491 DCHECK(args.length() == 1);
4492 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4493
4494 subject = String::Flatten(subject);
4495 double value = StringToDouble(isolate->unicode_cache(), *subject,
4496 ALLOW_TRAILING_JUNK, base::OS::nan_value());
4497
4498 return *isolate->factory()->NewNumber(value);
4499 }
4500
4501
4502 RUNTIME_FUNCTION(Runtime_NewStringWrapper) { 3213 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
4503 HandleScope scope(isolate); 3214 HandleScope scope(isolate);
4504 DCHECK(args.length() == 1); 3215 DCHECK(args.length() == 1);
4505 CONVERT_ARG_HANDLE_CHECKED(String, value, 0); 3216 CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
4506 return *Object::ToObject(isolate, value).ToHandleChecked(); 3217 return *Object::ToObject(isolate, value).ToHandleChecked();
4507 } 3218 }
4508 3219
4509 3220
4510 RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
4511 HandleScope scope(isolate);
4512 DCHECK(args.length() == 1);
4513 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
4514
4515 return *isolate->factory()->NumberToString(number);
4516 }
4517
4518
4519 RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
4520 HandleScope scope(isolate);
4521 DCHECK(args.length() == 1);
4522 CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
4523
4524 return *isolate->factory()->NumberToString(number, false);
4525 }
4526
4527
4528 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
4529 HandleScope scope(isolate);
4530 DCHECK(args.length() == 1);
4531
4532 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
4533 return *isolate->factory()->NewNumber(DoubleToInteger(number));
4534 }
4535
4536
4537 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
4538 HandleScope scope(isolate);
4539 DCHECK(args.length() == 1);
4540
4541 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
4542 double double_value = DoubleToInteger(number);
4543 // Map both -0 and +0 to +0.
4544 if (double_value == 0) double_value = 0;
4545
4546 return *isolate->factory()->NewNumber(double_value);
4547 }
4548
4549
4550 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
4551 HandleScope scope(isolate);
4552 DCHECK(args.length() == 1);
4553
4554 CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
4555 return *isolate->factory()->NewNumberFromUint(number);
4556 }
4557
4558
4559 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
4560 HandleScope scope(isolate);
4561 DCHECK(args.length() == 1);
4562
4563 CONVERT_DOUBLE_ARG_CHECKED(number, 0);
4564 return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
4565 }
4566
4567
4568 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
4569 // a small integer.
4570 RUNTIME_FUNCTION(Runtime_NumberToSmi) {
4571 SealHandleScope shs(isolate);
4572 DCHECK(args.length() == 1);
4573 CONVERT_ARG_CHECKED(Object, obj, 0);
4574 if (obj->IsSmi()) {
4575 return obj;
4576 }
4577 if (obj->IsHeapNumber()) {
4578 double value = HeapNumber::cast(obj)->value();
4579 int int_value = FastD2I(value);
4580 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
4581 return Smi::FromInt(int_value);
4582 }
4583 }
4584 return isolate->heap()->nan_value();
4585 }
4586
4587
4588 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { 3221 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
4589 HandleScope scope(isolate); 3222 HandleScope scope(isolate);
4590 DCHECK(args.length() == 0); 3223 DCHECK(args.length() == 0);
4591 return *isolate->factory()->NewHeapNumber(0); 3224 return *isolate->factory()->NewHeapNumber(0);
4592 } 3225 }
4593 3226
4594 3227
4595 RUNTIME_FUNCTION(Runtime_NumberAdd) { 3228
4596 HandleScope scope(isolate);
4597 DCHECK(args.length() == 2);
4598
4599 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4600 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4601 return *isolate->factory()->NewNumber(x + y);
4602 }
4603
4604
4605 RUNTIME_FUNCTION(Runtime_NumberSub) {
4606 HandleScope scope(isolate);
4607 DCHECK(args.length() == 2);
4608
4609 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4610 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4611 return *isolate->factory()->NewNumber(x - y);
4612 }
4613
4614
4615 RUNTIME_FUNCTION(Runtime_NumberMul) {
4616 HandleScope scope(isolate);
4617 DCHECK(args.length() == 2);
4618
4619 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4620 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4621 return *isolate->factory()->NewNumber(x * y);
4622 }
4623
4624
4625 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
4626 HandleScope scope(isolate);
4627 DCHECK(args.length() == 1);
4628
4629 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4630 return *isolate->factory()->NewNumber(-x);
4631 }
4632
4633
4634 RUNTIME_FUNCTION(Runtime_NumberDiv) {
4635 HandleScope scope(isolate);
4636 DCHECK(args.length() == 2);
4637
4638 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4639 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4640 return *isolate->factory()->NewNumber(x / y);
4641 }
4642
4643
4644 RUNTIME_FUNCTION(Runtime_NumberMod) {
4645 HandleScope scope(isolate);
4646 DCHECK(args.length() == 2);
4647
4648 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4649 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4650 return *isolate->factory()->NewNumber(modulo(x, y));
4651 }
4652
4653
4654 RUNTIME_FUNCTION(Runtime_NumberImul) {
4655 HandleScope scope(isolate);
4656 DCHECK(args.length() == 2);
4657
4658 // We rely on implementation-defined behavior below, but at least not on
4659 // undefined behavior.
4660 CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
4661 CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
4662 int32_t product = static_cast<int32_t>(x * y);
4663 return *isolate->factory()->NewNumberFromInt(product);
4664 }
4665
4666
4667 RUNTIME_FUNCTION(Runtime_NumberOr) {
4668 HandleScope scope(isolate);
4669 DCHECK(args.length() == 2);
4670
4671 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4672 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4673 return *isolate->factory()->NewNumberFromInt(x | y);
4674 }
4675
4676
4677 RUNTIME_FUNCTION(Runtime_NumberAnd) {
4678 HandleScope scope(isolate);
4679 DCHECK(args.length() == 2);
4680
4681 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4682 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4683 return *isolate->factory()->NewNumberFromInt(x & y);
4684 }
4685
4686
4687 RUNTIME_FUNCTION(Runtime_NumberXor) {
4688 HandleScope scope(isolate);
4689 DCHECK(args.length() == 2);
4690
4691 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4692 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4693 return *isolate->factory()->NewNumberFromInt(x ^ y);
4694 }
4695
4696
4697 RUNTIME_FUNCTION(Runtime_NumberShl) {
4698 HandleScope scope(isolate);
4699 DCHECK(args.length() == 2);
4700
4701 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4702 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4703 return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
4704 }
4705
4706
4707 RUNTIME_FUNCTION(Runtime_NumberShr) {
4708 HandleScope scope(isolate);
4709 DCHECK(args.length() == 2);
4710
4711 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
4712 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4713 return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
4714 }
4715
4716
4717 RUNTIME_FUNCTION(Runtime_NumberSar) {
4718 HandleScope scope(isolate);
4719 DCHECK(args.length() == 2);
4720
4721 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
4722 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
4723 return *isolate->factory()->NewNumberFromInt(
4724 ArithmeticShiftRight(x, y & 0x1f));
4725 }
4726
4727
4728 RUNTIME_FUNCTION(Runtime_NumberEquals) {
4729 SealHandleScope shs(isolate);
4730 DCHECK(args.length() == 2);
4731
4732 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4733 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4734 if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
4735 if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
4736 if (x == y) return Smi::FromInt(EQUAL);
4737 Object* result;
4738 if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
4739 result = Smi::FromInt(EQUAL);
4740 } else {
4741 result = Smi::FromInt(NOT_EQUAL);
4742 }
4743 return result;
4744 }
4745
4746
4747 RUNTIME_FUNCTION(Runtime_NumberCompare) {
4748 SealHandleScope shs(isolate);
4749 DCHECK(args.length() == 3);
4750
4751 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4752 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4753 CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
4754 if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
4755 if (x == y) return Smi::FromInt(EQUAL);
4756 if (isless(x, y)) return Smi::FromInt(LESS);
4757 return Smi::FromInt(GREATER);
4758 }
4759
4760
4761 // Compare two Smis as if they were converted to strings and then
4762 // compared lexicographically.
4763 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
4764 SealHandleScope shs(isolate);
4765 DCHECK(args.length() == 2);
4766 CONVERT_SMI_ARG_CHECKED(x_value, 0);
4767 CONVERT_SMI_ARG_CHECKED(y_value, 1);
4768
4769 // If the integers are equal so are the string representations.
4770 if (x_value == y_value) return Smi::FromInt(EQUAL);
4771
4772 // If one of the integers is zero the normal integer order is the
4773 // same as the lexicographic order of the string representations.
4774 if (x_value == 0 || y_value == 0)
4775 return Smi::FromInt(x_value < y_value ? LESS : GREATER);
4776
4777 // If only one of the integers is negative the negative number is
4778 // smallest because the char code of '-' is less than the char code
4779 // of any digit. Otherwise, we make both values positive.
4780
4781 // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
4782 // architectures using 32-bit Smis.
4783 uint32_t x_scaled = x_value;
4784 uint32_t y_scaled = y_value;
4785 if (x_value < 0 || y_value < 0) {
4786 if (y_value >= 0) return Smi::FromInt(LESS);
4787 if (x_value >= 0) return Smi::FromInt(GREATER);
4788 x_scaled = -x_value;
4789 y_scaled = -y_value;
4790 }
4791
4792 static const uint32_t kPowersOf10[] = {
4793 1, 10, 100, 1000,
4794 10 * 1000, 100 * 1000, 1000 * 1000, 10 * 1000 * 1000,
4795 100 * 1000 * 1000, 1000 * 1000 * 1000};
4796
4797 // If the integers have the same number of decimal digits they can be
4798 // compared directly as the numeric order is the same as the
4799 // lexicographic order. If one integer has fewer digits, it is scaled
4800 // by some power of 10 to have the same number of digits as the longer
4801 // integer. If the scaled integers are equal it means the shorter
4802 // integer comes first in the lexicographic order.
4803
4804 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
4805 int x_log2 = IntegerLog2(x_scaled);
4806 int x_log10 = ((x_log2 + 1) * 1233) >> 12;
4807 x_log10 -= x_scaled < kPowersOf10[x_log10];
4808
4809 int y_log2 = IntegerLog2(y_scaled);
4810 int y_log10 = ((y_log2 + 1) * 1233) >> 12;
4811 y_log10 -= y_scaled < kPowersOf10[y_log10];
4812
4813 int tie = EQUAL;
4814
4815 if (x_log10 < y_log10) {
4816 // X has fewer digits. We would like to simply scale up X but that
4817 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
4818 // be scaled up to 9_000_000_000. So we scale up by the next
4819 // smallest power and scale down Y to drop one digit. It is OK to
4820 // drop one digit from the longer integer since the final digit is
4821 // past the length of the shorter integer.
4822 x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
4823 y_scaled /= 10;
4824 tie = LESS;
4825 } else if (y_log10 < x_log10) {
4826 y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
4827 x_scaled /= 10;
4828 tie = GREATER;
4829 }
4830
4831 if (x_scaled < y_scaled) return Smi::FromInt(LESS);
4832 if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
4833 return Smi::FromInt(tie);
4834 }
4835
4836
4837
4838
4839
4840 #define RUNTIME_UNARY_MATH(Name, name) \
4841 RUNTIME_FUNCTION(Runtime_Math##Name) { \
4842 HandleScope scope(isolate); \
4843 DCHECK(args.length() == 1); \
4844 isolate->counters()->math_##name()->Increment(); \
4845 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \
4846 return *isolate->factory()->NewHeapNumber(std::name(x)); \
4847 }
4848
4849 RUNTIME_UNARY_MATH(Acos, acos)
4850 RUNTIME_UNARY_MATH(Asin, asin)
4851 RUNTIME_UNARY_MATH(Atan, atan)
4852 RUNTIME_UNARY_MATH(LogRT, log)
4853 #undef RUNTIME_UNARY_MATH
4854
4855
4856 RUNTIME_FUNCTION(Runtime_DoubleHi) {
4857 HandleScope scope(isolate);
4858 DCHECK(args.length() == 1);
4859 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4860 uint64_t integer = double_to_uint64(x);
4861 integer = (integer >> 32) & 0xFFFFFFFFu;
4862 return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
4863 }
4864
4865
4866 RUNTIME_FUNCTION(Runtime_DoubleLo) {
4867 HandleScope scope(isolate);
4868 DCHECK(args.length() == 1);
4869 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4870 return *isolate->factory()->NewNumber(
4871 static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
4872 }
4873
4874
4875 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
4876 HandleScope scope(isolate);
4877 DCHECK(args.length() == 2);
4878 CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
4879 CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
4880 uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
4881 return *isolate->factory()->NewNumber(uint64_to_double(result));
4882 }
4883
4884
4885 RUNTIME_FUNCTION(Runtime_RemPiO2) {
4886 HandleScope handle_scope(isolate);
4887 DCHECK(args.length() == 1);
4888 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4889 Factory* factory = isolate->factory();
4890 double y[2];
4891 int n = fdlibm::rempio2(x, y);
4892 Handle<FixedArray> array = factory->NewFixedArray(3);
4893 Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
4894 Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
4895 array->set(0, Smi::FromInt(n));
4896 array->set(1, *y0);
4897 array->set(2, *y1);
4898 return *factory->NewJSArrayWithElements(array);
4899 }
4900
4901
4902 static const double kPiDividedBy4 = 0.78539816339744830962;
4903
4904
4905 RUNTIME_FUNCTION(Runtime_MathAtan2) {
4906 HandleScope scope(isolate);
4907 DCHECK(args.length() == 2);
4908 isolate->counters()->math_atan2()->Increment();
4909
4910 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4911 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4912 double result;
4913 if (std::isinf(x) && std::isinf(y)) {
4914 // Make sure that the result in case of two infinite arguments
4915 // is a multiple of Pi / 4. The sign of the result is determined
4916 // by the first argument (x) and the sign of the second argument
4917 // determines the multiplier: one or three.
4918 int multiplier = (x < 0) ? -1 : 1;
4919 if (y < 0) multiplier *= 3;
4920 result = multiplier * kPiDividedBy4;
4921 } else {
4922 result = std::atan2(x, y);
4923 }
4924 return *isolate->factory()->NewNumber(result);
4925 }
4926
4927
4928 RUNTIME_FUNCTION(Runtime_MathExpRT) {
4929 HandleScope scope(isolate);
4930 DCHECK(args.length() == 1);
4931 isolate->counters()->math_exp()->Increment();
4932
4933 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4934 lazily_initialize_fast_exp();
4935 return *isolate->factory()->NewNumber(fast_exp(x));
4936 }
4937
4938
4939 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
4940 HandleScope scope(isolate);
4941 DCHECK(args.length() == 1);
4942 isolate->counters()->math_floor()->Increment();
4943
4944 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4945 return *isolate->factory()->NewNumber(Floor(x));
4946 }
4947
4948
4949 // Slow version of Math.pow. We check for fast paths for special cases.
4950 // Used if VFP3 is not available.
4951 RUNTIME_FUNCTION(Runtime_MathPowSlow) {
4952 HandleScope scope(isolate);
4953 DCHECK(args.length() == 2);
4954 isolate->counters()->math_pow()->Increment();
4955
4956 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4957
4958 // If the second argument is a smi, it is much faster to call the
4959 // custom powi() function than the generic pow().
4960 if (args[1]->IsSmi()) {
4961 int y = args.smi_at(1);
4962 return *isolate->factory()->NewNumber(power_double_int(x, y));
4963 }
4964
4965 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4966 double result = power_helper(x, y);
4967 if (std::isnan(result)) return isolate->heap()->nan_value();
4968 return *isolate->factory()->NewNumber(result);
4969 }
4970
4971
4972 // Fast version of Math.pow if we know that y is not an integer and y is not
4973 // -0.5 or 0.5. Used as slow case from full codegen.
4974 RUNTIME_FUNCTION(Runtime_MathPowRT) {
4975 HandleScope scope(isolate);
4976 DCHECK(args.length() == 2);
4977 isolate->counters()->math_pow()->Increment();
4978
4979 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4980 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
4981 if (y == 0) {
4982 return Smi::FromInt(1);
4983 } else {
4984 double result = power_double_double(x, y);
4985 if (std::isnan(result)) return isolate->heap()->nan_value();
4986 return *isolate->factory()->NewNumber(result);
4987 }
4988 }
4989
4990
4991 RUNTIME_FUNCTION(Runtime_RoundNumber) {
4992 HandleScope scope(isolate);
4993 DCHECK(args.length() == 1);
4994 CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
4995 isolate->counters()->math_round()->Increment();
4996
4997 if (!input->IsHeapNumber()) {
4998 DCHECK(input->IsSmi());
4999 return *input;
5000 }
5001
5002 Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
5003
5004 double value = number->value();
5005 int exponent = number->get_exponent();
5006 int sign = number->get_sign();
5007
5008 if (exponent < -1) {
5009 // Number in range ]-0.5..0.5[. These always round to +/-zero.
5010 if (sign) return isolate->heap()->minus_zero_value();
5011 return Smi::FromInt(0);
5012 }
5013
5014 // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
5015 // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
5016 // argument holds for 32-bit smis).
5017 if (!sign && exponent < kSmiValueSize - 2) {
5018 return Smi::FromInt(static_cast<int>(value + 0.5));
5019 }
5020
5021 // If the magnitude is big enough, there's no place for fraction part. If we
5022 // try to add 0.5 to this number, 1.0 will be added instead.
5023 if (exponent >= 52) {
5024 return *number;
5025 }
5026
5027 if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
5028
5029 // Do not call NumberFromDouble() to avoid extra checks.
5030 return *isolate->factory()->NewNumber(Floor(value + 0.5));
5031 }
5032
5033
5034 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
5035 HandleScope scope(isolate);
5036 DCHECK(args.length() == 1);
5037 isolate->counters()->math_sqrt()->Increment();
5038
5039 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5040 return *isolate->factory()->NewNumber(fast_sqrt(x));
5041 }
5042
5043
5044 RUNTIME_FUNCTION(Runtime_MathFround) {
5045 HandleScope scope(isolate);
5046 DCHECK(args.length() == 1);
5047
5048 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5049 float xf = DoubleToFloat32(x);
5050 return *isolate->factory()->NewNumber(xf);
5051 }
5052 3229
5053 3230
5054 RUNTIME_FUNCTION(Runtime_DateMakeDay) { 3231 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
5055 SealHandleScope shs(isolate); 3232 SealHandleScope shs(isolate);
5056 DCHECK(args.length() == 2); 3233 DCHECK(args.length() == 2);
5057 3234
5058 CONVERT_SMI_ARG_CHECKED(year, 0); 3235 CONVERT_SMI_ARG_CHECKED(year, 0);
5059 CONVERT_SMI_ARG_CHECKED(month, 1); 3236 CONVERT_SMI_ARG_CHECKED(month, 1);
5060 3237
5061 int days = isolate->date_cache()->DaysFromYearMonth(year, month); 3238 int days = isolate->date_cache()->DaysFromYearMonth(year, month);
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
5535 RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) { 3712 RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
5536 HandleScope scope(isolate); 3713 HandleScope scope(isolate);
5537 DCHECK(args.length() == 1); 3714 DCHECK(args.length() == 1);
5538 3715
5539 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 3716 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5540 function->CompleteInobjectSlackTracking(); 3717 function->CompleteInobjectSlackTracking();
5541 3718
5542 return isolate->heap()->undefined_value(); 3719 return isolate->heap()->undefined_value();
5543 } 3720 }
5544 3721
5545
5546 RUNTIME_FUNCTION(Runtime_CompileLazy) {
5547 HandleScope scope(isolate);
5548 DCHECK(args.length() == 1);
5549 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5550 #ifdef DEBUG
5551 if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
5552 PrintF("[unoptimized: ");
5553 function->PrintName();
5554 PrintF("]\n");
5555 }
5556 #endif
5557
5558 // Compile the target function.
5559 DCHECK(function->shared()->allows_lazy_compilation());
5560
5561 Handle<Code> code;
5562 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
5563 Compiler::GetLazyCode(function));
5564 DCHECK(code->kind() == Code::FUNCTION ||
5565 code->kind() == Code::OPTIMIZED_FUNCTION);
5566 function->ReplaceCode(*code);
5567 return *code;
5568 }
5569
5570
5571 RUNTIME_FUNCTION(Runtime_CompileOptimized) {
5572 HandleScope scope(isolate);
5573 DCHECK(args.length() == 2);
5574 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5575 CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
5576
5577 Handle<Code> unoptimized(function->shared()->code());
5578 if (!isolate->use_crankshaft() ||
5579 function->shared()->optimization_disabled() ||
5580 isolate->DebuggerHasBreakPoints()) {
5581 // If the function is not optimizable or debugger is active continue
5582 // using the code from the full compiler.
5583 if (FLAG_trace_opt) {
5584 PrintF("[failed to optimize ");
5585 function->PrintName();
5586 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
5587 function->shared()->optimization_disabled() ? "F" : "T",
5588 isolate->DebuggerHasBreakPoints() ? "T" : "F");
5589 }
5590 function->ReplaceCode(*unoptimized);
5591 return function->code();
5592 }
5593
5594 Compiler::ConcurrencyMode mode =
5595 concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
5596 Handle<Code> code;
5597 if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
5598 function->ReplaceCode(*code);
5599 } else {
5600 function->ReplaceCode(function->shared()->code());
5601 }
5602
5603 DCHECK(function->code()->kind() == Code::FUNCTION ||
5604 function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
5605 function->IsInOptimizationQueue());
5606 return function->code();
5607 }
5608
5609
5610 class ActivationsFinder : public ThreadVisitor {
5611 public:
5612 Code* code_;
5613 bool has_code_activations_;
5614
5615 explicit ActivationsFinder(Code* code)
5616 : code_(code), has_code_activations_(false) {}
5617
5618 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
5619 JavaScriptFrameIterator it(isolate, top);
5620 VisitFrames(&it);
5621 }
5622
5623 void VisitFrames(JavaScriptFrameIterator* it) {
5624 for (; !it->done(); it->Advance()) {
5625 JavaScriptFrame* frame = it->frame();
5626 if (code_->contains(frame->pc())) has_code_activations_ = true;
5627 }
5628 }
5629 };
5630
5631
5632 RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
5633 HandleScope scope(isolate);
5634 DCHECK(args.length() == 0);
5635 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
5636 DCHECK(AllowHeapAllocation::IsAllowed());
5637 delete deoptimizer;
5638 return isolate->heap()->undefined_value();
5639 }
5640
5641
5642 RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
5643 HandleScope scope(isolate);
5644 DCHECK(args.length() == 1);
5645 CONVERT_SMI_ARG_CHECKED(type_arg, 0);
5646 Deoptimizer::BailoutType type =
5647 static_cast<Deoptimizer::BailoutType>(type_arg);
5648 Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
5649 DCHECK(AllowHeapAllocation::IsAllowed());
5650
5651 Handle<JSFunction> function = deoptimizer->function();
5652 Handle<Code> optimized_code = deoptimizer->compiled_code();
5653
5654 DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
5655 DCHECK(type == deoptimizer->bailout_type());
5656
5657 // Make sure to materialize objects before causing any allocation.
5658 JavaScriptFrameIterator it(isolate);
5659 deoptimizer->MaterializeHeapObjects(&it);
5660 delete deoptimizer;
5661
5662 JavaScriptFrame* frame = it.frame();
5663 RUNTIME_ASSERT(frame->function()->IsJSFunction());
5664 DCHECK(frame->function() == *function);
5665
5666 // Avoid doing too much work when running with --always-opt and keep
5667 // the optimized code around.
5668 if (FLAG_always_opt || type == Deoptimizer::LAZY) {
5669 return isolate->heap()->undefined_value();
5670 }
5671
5672 // Search for other activations of the same function and code.
5673 ActivationsFinder activations_finder(*optimized_code);
5674 activations_finder.VisitFrames(&it);
5675 isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
5676
5677 if (!activations_finder.has_code_activations_) {
5678 if (function->code() == *optimized_code) {
5679 if (FLAG_trace_deopt) {
5680 PrintF("[removing optimized code for: ");
5681 function->PrintName();
5682 PrintF("]\n");
5683 }
5684 function->ReplaceCode(function->shared()->code());
5685 // Evict optimized code for this function from the cache so that it
5686 // doesn't get used for new closures.
5687 function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
5688 "notify deoptimized");
5689 }
5690 } else {
5691 // TODO(titzer): we should probably do DeoptimizeCodeList(code)
5692 // unconditionally if the code is not already marked for deoptimization.
5693 // If there is an index by shared function info, all the better.
5694 Deoptimizer::DeoptimizeFunction(*function);
5695 }
5696
5697 return isolate->heap()->undefined_value();
5698 }
5699
5700
5701 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
5702 HandleScope scope(isolate);
5703 DCHECK(args.length() == 1);
5704 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5705 if (!function->IsOptimized()) return isolate->heap()->undefined_value();
5706
5707 // TODO(turbofan): Deoptimization is not supported yet.
5708 if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
5709 return isolate->heap()->undefined_value();
5710 }
5711
5712 Deoptimizer::DeoptimizeFunction(*function);
5713
5714 return isolate->heap()->undefined_value();
5715 }
5716
5717
5718 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
5719 HandleScope scope(isolate);
5720 DCHECK(args.length() == 1);
5721 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5722 function->shared()->ClearTypeFeedbackInfo();
5723 Code* unoptimized = function->shared()->code();
5724 if (unoptimized->kind() == Code::FUNCTION) {
5725 unoptimized->ClearInlineCaches();
5726 }
5727 return isolate->heap()->undefined_value();
5728 }
5729
5730
5731 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
5732 SealHandleScope shs(isolate);
5733 DCHECK(args.length() == 0);
5734 #if defined(USE_SIMULATOR)
5735 return isolate->heap()->true_value();
5736 #else
5737 return isolate->heap()->false_value();
5738 #endif
5739 }
5740
5741
5742 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
5743 SealHandleScope shs(isolate);
5744 DCHECK(args.length() == 0);
5745 return isolate->heap()->ToBoolean(
5746 isolate->concurrent_recompilation_enabled());
5747 }
5748
5749
5750 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
5751 HandleScope scope(isolate);
5752 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
5753 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5754 // The following two assertions are lifted from the DCHECKs inside
5755 // JSFunction::MarkForOptimization().
5756 RUNTIME_ASSERT(!function->shared()->is_generator());
5757 RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
5758 (function->code()->kind() == Code::FUNCTION &&
5759 function->code()->optimizable()));
5760
5761 // If the function is optimized, just return.
5762 if (function->IsOptimized()) return isolate->heap()->undefined_value();
5763
5764 function->MarkForOptimization();
5765
5766 Code* unoptimized = function->shared()->code();
5767 if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
5768 CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
5769 if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
5770 // Start patching from the currently patched loop nesting level.
5771 DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
5772 isolate->runtime_profiler()->AttemptOnStackReplacement(
5773 *function, Code::kMaxLoopNestingMarker);
5774 } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
5775 isolate->concurrent_recompilation_enabled()) {
5776 function->MarkForConcurrentOptimization();
5777 }
5778 }
5779
5780 return isolate->heap()->undefined_value();
5781 }
5782
5783
5784 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
5785 HandleScope scope(isolate);
5786 DCHECK(args.length() == 1);
5787 CONVERT_ARG_CHECKED(JSFunction, function, 0);
5788 function->shared()->set_optimization_disabled(true);
5789 return isolate->heap()->undefined_value();
5790 }
5791
5792
5793 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
5794 HandleScope scope(isolate);
5795 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
5796 if (!isolate->use_crankshaft()) {
5797 return Smi::FromInt(4); // 4 == "never".
5798 }
5799 bool sync_with_compiler_thread = true;
5800 if (args.length() == 2) {
5801 CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
5802 if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
5803 sync_with_compiler_thread = false;
5804 }
5805 }
5806 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5807 if (isolate->concurrent_recompilation_enabled() &&
5808 sync_with_compiler_thread) {
5809 while (function->IsInOptimizationQueue()) {
5810 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
5811 base::OS::Sleep(50);
5812 }
5813 }
5814 if (FLAG_always_opt) {
5815 // We may have always opt, but that is more best-effort than a real
5816 // promise, so we still say "no" if it is not optimized.
5817 return function->IsOptimized() ? Smi::FromInt(3) // 3 == "always".
5818 : Smi::FromInt(2); // 2 == "no".
5819 }
5820 if (FLAG_deopt_every_n_times) {
5821 return Smi::FromInt(6); // 6 == "maybe deopted".
5822 }
5823 if (function->IsOptimized() && function->code()->is_turbofanned()) {
5824 return Smi::FromInt(7); // 7 == "TurboFan compiler".
5825 }
5826 return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes".
5827 : Smi::FromInt(2); // 2 == "no".
5828 }
5829
5830
5831 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
5832 DCHECK(args.length() == 0);
5833 RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
5834 RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
5835 isolate->optimizing_compiler_thread()->Unblock();
5836 return isolate->heap()->undefined_value();
5837 }
5838
5839
5840 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
5841 HandleScope scope(isolate);
5842 DCHECK(args.length() == 1);
5843 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5844 return Smi::FromInt(function->shared()->opt_count());
5845 }
5846
5847
5848 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
5849 Handle<JSFunction> function,
5850 Handle<Code> current_code) {
5851 // Keep track of whether we've succeeded in optimizing.
5852 if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
5853 // If we are trying to do OSR when there are already optimized
5854 // activations of the function, it means (a) the function is directly or
5855 // indirectly recursive and (b) an optimized invocation has been
5856 // deoptimized so that we are currently in an unoptimized activation.
5857 // Check for optimized activations of this function.
5858 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
5859 JavaScriptFrame* frame = it.frame();
5860 if (frame->is_optimized() && frame->function() == *function) return false;
5861 }
5862
5863 return true;
5864 }
5865
5866
5867 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
5868 HandleScope scope(isolate);
5869 DCHECK(args.length() == 1);
5870 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
5871 Handle<Code> caller_code(function->shared()->code());
5872
5873 // We're not prepared to handle a function with arguments object.
5874 DCHECK(!function->shared()->uses_arguments());
5875
5876 RUNTIME_ASSERT(FLAG_use_osr);
5877
5878 // Passing the PC in the javascript frame from the caller directly is
5879 // not GC safe, so we walk the stack to get it.
5880 JavaScriptFrameIterator it(isolate);
5881 JavaScriptFrame* frame = it.frame();
5882 if (!caller_code->contains(frame->pc())) {
5883 // Code on the stack may not be the code object referenced by the shared
5884 // function info. It may have been replaced to include deoptimization data.
5885 caller_code = Handle<Code>(frame->LookupCode());
5886 }
5887
5888 uint32_t pc_offset =
5889 static_cast<uint32_t>(frame->pc() - caller_code->instruction_start());
5890
5891 #ifdef DEBUG
5892 DCHECK_EQ(frame->function(), *function);
5893 DCHECK_EQ(frame->LookupCode(), *caller_code);
5894 DCHECK(caller_code->contains(frame->pc()));
5895 #endif // DEBUG
5896
5897
5898 BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
5899 DCHECK(!ast_id.IsNone());
5900
5901 Compiler::ConcurrencyMode mode =
5902 isolate->concurrent_osr_enabled() &&
5903 (function->shared()->ast_node_count() > 512)
5904 ? Compiler::CONCURRENT
5905 : Compiler::NOT_CONCURRENT;
5906 Handle<Code> result = Handle<Code>::null();
5907
5908 OptimizedCompileJob* job = NULL;
5909 if (mode == Compiler::CONCURRENT) {
5910 // Gate the OSR entry with a stack check.
5911 BackEdgeTable::AddStackCheck(caller_code, pc_offset);
5912 // Poll already queued compilation jobs.
5913 OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
5914 if (thread->IsQueuedForOSR(function, ast_id)) {
5915 if (FLAG_trace_osr) {
5916 PrintF("[OSR - Still waiting for queued: ");
5917 function->PrintName();
5918 PrintF(" at AST id %d]\n", ast_id.ToInt());
5919 }
5920 return NULL;
5921 }
5922
5923 job = thread->FindReadyOSRCandidate(function, ast_id);
5924 }
5925
5926 if (job != NULL) {
5927 if (FLAG_trace_osr) {
5928 PrintF("[OSR - Found ready: ");
5929 function->PrintName();
5930 PrintF(" at AST id %d]\n", ast_id.ToInt());
5931 }
5932 result = Compiler::GetConcurrentlyOptimizedCode(job);
5933 } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
5934 if (FLAG_trace_osr) {
5935 PrintF("[OSR - Compiling: ");
5936 function->PrintName();
5937 PrintF(" at AST id %d]\n", ast_id.ToInt());
5938 }
5939 MaybeHandle<Code> maybe_result =
5940 Compiler::GetOptimizedCode(function, caller_code, mode, ast_id);
5941 if (maybe_result.ToHandle(&result) &&
5942 result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
5943 // Optimization is queued. Return to check later.
5944 return NULL;
5945 }
5946 }
5947
5948 // Revert the patched back edge table, regardless of whether OSR succeeds.
5949 BackEdgeTable::Revert(isolate, *caller_code);
5950
5951 // Check whether we ended up with usable optimized code.
5952 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
5953 DeoptimizationInputData* data =
5954 DeoptimizationInputData::cast(result->deoptimization_data());
5955
5956 if (data->OsrPcOffset()->value() >= 0) {
5957 DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
5958 if (FLAG_trace_osr) {
5959 PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
5960 ast_id.ToInt(), data->OsrPcOffset()->value());
5961 }
5962 // TODO(titzer): this is a massive hack to make the deopt counts
5963 // match. Fix heuristics for reenabling optimizations!
5964 function->shared()->increment_deopt_count();
5965
5966 // TODO(titzer): Do not install code into the function.
5967 function->ReplaceCode(*result);
5968 return *result;
5969 }
5970 }
5971
5972 // Failed.
5973 if (FLAG_trace_osr) {
5974 PrintF("[OSR - Failed: ");
5975 function->PrintName();
5976 PrintF(" at AST id %d]\n", ast_id.ToInt());
5977 }
5978
5979 if (!function->IsOptimized()) {
5980 function->ReplaceCode(function->shared()->code());
5981 }
5982 return NULL;
5983 }
5984
5985
5986 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
5987 SealHandleScope shs(isolate);
5988 DCHECK(args.length() == 2 || args.length() == 3);
5989 #ifdef DEBUG
5990 CONVERT_SMI_ARG_CHECKED(interval, 0);
5991 CONVERT_SMI_ARG_CHECKED(timeout, 1);
5992 isolate->heap()->set_allocation_timeout(timeout);
5993 FLAG_gc_interval = interval;
5994 if (args.length() == 3) {
5995 // Enable/disable inline allocation if requested.
5996 CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
5997 if (inline_allocation) {
5998 isolate->heap()->EnableInlineAllocation();
5999 } else {
6000 isolate->heap()->DisableInlineAllocation();
6001 }
6002 }
6003 #endif
6004 return isolate->heap()->undefined_value();
6005 }
6006
6007 3722
6008 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { 3723 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
6009 SealHandleScope shs(isolate); 3724 SealHandleScope shs(isolate);
6010 DCHECK(args.length() == 0); 3725 DCHECK(args.length() == 0);
6011 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); 3726 RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
6012 return isolate->heap()->undefined_value(); 3727 return isolate->heap()->undefined_value();
6013 } 3728 }
6014 3729
6015 3730
6016 RUNTIME_FUNCTION(Runtime_GetRootNaN) { 3731 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
6598 // First check if this is a real stack overflow. 4313 // First check if this is a real stack overflow.
6599 StackLimitCheck check(isolate); 4314 StackLimitCheck check(isolate);
6600 if (check.JsHasOverflowed()) { 4315 if (check.JsHasOverflowed()) {
6601 return isolate->StackOverflow(); 4316 return isolate->StackOverflow();
6602 } 4317 }
6603 4318
6604 return isolate->stack_guard()->HandleInterrupts(); 4319 return isolate->stack_guard()->HandleInterrupts();
6605 } 4320 }
6606 4321
6607 4322
6608 RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
6609 HandleScope scope(isolate);
6610 DCHECK(args.length() == 1);
6611 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
6612
6613 // First check if this is a real stack overflow.
6614 StackLimitCheck check(isolate);
6615 if (check.JsHasOverflowed()) {
6616 SealHandleScope shs(isolate);
6617 return isolate->StackOverflow();
6618 }
6619
6620 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
6621 return (function->IsOptimized()) ? function->code()
6622 : function->shared()->code();
6623 }
6624
6625
6626 RUNTIME_FUNCTION(Runtime_Interrupt) { 4323 RUNTIME_FUNCTION(Runtime_Interrupt) {
6627 SealHandleScope shs(isolate); 4324 SealHandleScope shs(isolate);
6628 DCHECK(args.length() == 0); 4325 DCHECK(args.length() == 0);
6629 return isolate->stack_guard()->HandleInterrupts(); 4326 return isolate->stack_guard()->HandleInterrupts();
6630 } 4327 }
6631 4328
6632 4329
6633 static int StackSize(Isolate* isolate) { 4330 static int StackSize(Isolate* isolate) {
6634 int n = 0; 4331 int n = 0;
6635 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++; 4332 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6670 4367
6671 RUNTIME_FUNCTION(Runtime_TraceExit) { 4368 RUNTIME_FUNCTION(Runtime_TraceExit) {
6672 SealHandleScope shs(isolate); 4369 SealHandleScope shs(isolate);
6673 DCHECK(args.length() == 1); 4370 DCHECK(args.length() == 1);
6674 CONVERT_ARG_CHECKED(Object, obj, 0); 4371 CONVERT_ARG_CHECKED(Object, obj, 0);
6675 PrintTransition(isolate, obj); 4372 PrintTransition(isolate, obj);
6676 return obj; // return TOS 4373 return obj; // return TOS
6677 } 4374 }
6678 4375
6679 4376
6680 RUNTIME_FUNCTION(Runtime_DebugPrint) {
6681 SealHandleScope shs(isolate);
6682 DCHECK(args.length() == 1);
6683
6684 OFStream os(stdout);
6685 #ifdef DEBUG
6686 if (args[0]->IsString()) {
6687 // If we have a string, assume it's a code "marker"
6688 // and print some interesting cpu debugging info.
6689 JavaScriptFrameIterator it(isolate);
6690 JavaScriptFrame* frame = it.frame();
6691 os << "fp = " << frame->fp() << ", sp = " << frame->sp()
6692 << ", caller_sp = " << frame->caller_sp() << ": ";
6693 } else {
6694 os << "DebugPrint: ";
6695 }
6696 args[0]->Print(os);
6697 if (args[0]->IsHeapObject()) {
6698 os << "\n";
6699 HeapObject::cast(args[0])->map()->Print(os);
6700 }
6701 #else
6702 // ShortPrint is available in release mode. Print is not.
6703 os << Brief(args[0]);
6704 #endif
6705 os << endl;
6706
6707 return args[0]; // return TOS
6708 }
6709
6710
6711 RUNTIME_FUNCTION(Runtime_DebugTrace) {
6712 SealHandleScope shs(isolate);
6713 DCHECK(args.length() == 0);
6714 isolate->PrintStack(stdout);
6715 return isolate->heap()->undefined_value();
6716 }
6717
6718
6719 RUNTIME_FUNCTION(Runtime_DateCurrentTime) { 4377 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
6720 HandleScope scope(isolate); 4378 HandleScope scope(isolate);
6721 DCHECK(args.length() == 0); 4379 DCHECK(args.length() == 0);
6722 if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent()); 4380 if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
6723 4381
6724 // According to ECMA-262, section 15.9.1, page 117, the precision of 4382 // According to ECMA-262, section 15.9.1, page 117, the precision of
6725 // the number in a Date object representing a particular instant in 4383 // the number in a Date object representing a particular instant in
6726 // time is milliseconds. Therefore, we floor the result of getting 4384 // time is milliseconds. Therefore, we floor the result of getting
6727 // the OS time. 4385 // the OS time.
6728 double millis; 4386 double millis;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
6831 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { 4489 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
6832 SealHandleScope shs(isolate); 4490 SealHandleScope shs(isolate);
6833 DCHECK(args.length() == 1); 4491 DCHECK(args.length() == 1);
6834 CONVERT_ARG_CHECKED(Object, global, 0); 4492 CONVERT_ARG_CHECKED(Object, global, 0);
6835 if (!global->IsJSGlobalObject()) return isolate->heap()->false_value(); 4493 if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
6836 return isolate->heap()->ToBoolean( 4494 return isolate->heap()->ToBoolean(
6837 !JSGlobalObject::cast(global)->IsDetached()); 4495 !JSGlobalObject::cast(global)->IsDetached());
6838 } 4496 }
6839 4497
6840 4498
6841 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
6842 Handle<Context> context) {
6843 DCHECK(context->allow_code_gen_from_strings()->IsFalse());
6844 // Check with callback if set.
6845 AllowCodeGenerationFromStringsCallback callback =
6846 isolate->allow_code_gen_callback();
6847 if (callback == NULL) {
6848 // No callback set and code generation disallowed.
6849 return false;
6850 } else {
6851 // Callback set. Let it decide if code generation is allowed.
6852 VMState<EXTERNAL> state(isolate);
6853 return callback(v8::Utils::ToLocal(context));
6854 }
6855 }
6856
6857
6858 RUNTIME_FUNCTION(Runtime_CompileString) {
6859 HandleScope scope(isolate);
6860 DCHECK(args.length() == 2);
6861 CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6862 CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
6863
6864 // Extract native context.
6865 Handle<Context> context(isolate->native_context());
6866
6867 // Check if native context allows code generation from
6868 // strings. Throw an exception if it doesn't.
6869 if (context->allow_code_gen_from_strings()->IsFalse() &&
6870 !CodeGenerationFromStringsAllowed(isolate, context)) {
6871 Handle<Object> error_message =
6872 context->ErrorMessageForCodeGenerationFromStrings();
6873 THROW_NEW_ERROR_RETURN_FAILURE(
6874 isolate, NewEvalError("code_gen_from_strings",
6875 HandleVector<Object>(&error_message, 1)));
6876 }
6877
6878 // Compile source string in the native context.
6879 ParseRestriction restriction = function_literal_only
6880 ? ONLY_SINGLE_FUNCTION_LITERAL
6881 : NO_PARSE_RESTRICTION;
6882 Handle<JSFunction> fun;
6883 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6884 isolate, fun,
6885 Compiler::GetFunctionFromEval(source, context, SLOPPY, restriction,
6886 RelocInfo::kNoPosition));
6887 return *fun;
6888 }
6889
6890
6891 static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
6892 Handle<Object> receiver,
6893 StrictMode strict_mode,
6894 int scope_position) {
6895 Handle<Context> context = Handle<Context>(isolate->context());
6896 Handle<Context> native_context = Handle<Context>(context->native_context());
6897
6898 // Check if native context allows code generation from
6899 // strings. Throw an exception if it doesn't.
6900 if (native_context->allow_code_gen_from_strings()->IsFalse() &&
6901 !CodeGenerationFromStringsAllowed(isolate, native_context)) {
6902 Handle<Object> error_message =
6903 native_context->ErrorMessageForCodeGenerationFromStrings();
6904 Handle<Object> error;
6905 MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
6906 "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
6907 if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
6908 return MakePair(isolate->heap()->exception(), NULL);
6909 }
6910
6911 // Deal with a normal eval call with a string argument. Compile it
6912 // and return the compiled function bound in the local context.
6913 static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
6914 Handle<JSFunction> compiled;
6915 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
6916 isolate, compiled,
6917 Compiler::GetFunctionFromEval(source, context, strict_mode, restriction,
6918 scope_position),
6919 MakePair(isolate->heap()->exception(), NULL));
6920 return MakePair(*compiled, *receiver);
6921 }
6922
6923
6924 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
6925 HandleScope scope(isolate);
6926 DCHECK(args.length() == 5);
6927
6928 Handle<Object> callee = args.at<Object>(0);
6929
6930 // If "eval" didn't refer to the original GlobalEval, it's not a
6931 // direct call to eval.
6932 // (And even if it is, but the first argument isn't a string, just let
6933 // execution default to an indirect call to eval, which will also return
6934 // the first argument without doing anything).
6935 if (*callee != isolate->native_context()->global_eval_fun() ||
6936 !args[1]->IsString()) {
6937 return MakePair(*callee, isolate->heap()->undefined_value());
6938 }
6939
6940 DCHECK(args[3]->IsSmi());
6941 DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
6942 StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
6943 DCHECK(args[4]->IsSmi());
6944 return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2),
6945 strict_mode, args.smi_at(4));
6946 }
6947
6948
6949 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { 4499 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
6950 HandleScope scope(isolate); 4500 HandleScope scope(isolate);
6951 DCHECK(args.length() == 1); 4501 DCHECK(args.length() == 1);
6952 CONVERT_SMI_ARG_CHECKED(size, 0); 4502 CONVERT_SMI_ARG_CHECKED(size, 0);
6953 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); 4503 RUNTIME_ASSERT(IsAligned(size, kPointerSize));
6954 RUNTIME_ASSERT(size > 0); 4504 RUNTIME_ASSERT(size > 0);
6955 RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize); 4505 RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
6956 return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE); 4506 return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
6957 } 4507 }
6958 4508
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
7680 5230
7681 if (visitor.exceeds_array_limit()) { 5231 if (visitor.exceeds_array_limit()) {
7682 THROW_NEW_ERROR_RETURN_FAILURE( 5232 THROW_NEW_ERROR_RETURN_FAILURE(
7683 isolate, 5233 isolate,
7684 NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0))); 5234 NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
7685 } 5235 }
7686 return *visitor.ToArray(); 5236 return *visitor.ToArray();
7687 } 5237 }
7688 5238
7689 5239
7690 // This will not allocate (flatten the string), but it may run
7691 // very slowly for very deeply nested ConsStrings. For debugging use only.
7692 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
7693 SealHandleScope shs(isolate);
7694 DCHECK(args.length() == 1);
7695
7696 CONVERT_ARG_CHECKED(String, string, 0);
7697 ConsStringIteratorOp op;
7698 StringCharacterStream stream(string, &op);
7699 while (stream.HasMore()) {
7700 uint16_t character = stream.GetNext();
7701 PrintF("%c", character);
7702 }
7703 return string;
7704 }
7705
7706
7707 // Moves all own elements of an object, that are below a limit, to positions 5240 // Moves all own elements of an object, that are below a limit, to positions
7708 // starting at zero. All undefined values are placed after non-undefined values, 5241 // starting at zero. All undefined values are placed after non-undefined values,
7709 // and are followed by non-existing element. Does not change the length 5242 // and are followed by non-existing element. Does not change the length
7710 // property. 5243 // property.
7711 // Returns the number of non-undefined elements collected. 5244 // Returns the number of non-undefined elements collected.
7712 // Returns -1 if hole removal is not supported by this method. 5245 // Returns -1 if hole removal is not supported by this method.
7713 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) { 5246 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
7714 HandleScope scope(isolate); 5247 HandleScope scope(isolate);
7715 DCHECK(args.length() == 2); 5248 DCHECK(args.length() == 2);
7716 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5249 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
(...skipping 2586 matching lines...) Expand 10 before | Expand all | Expand 10 after
10303 Handle<Script> script(Script::cast(script_wrapper->value())); 7836 Handle<Script> script(Script::cast(script_wrapper->value()));
10304 7837
10305 int compilation_state = script->compilation_state(); 7838 int compilation_state = script->compilation_state();
10306 RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL); 7839 RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
10307 script->set_source(*source); 7840 script->set_source(*source);
10308 7841
10309 return isolate->heap()->undefined_value(); 7842 return isolate->heap()->undefined_value();
10310 } 7843 }
10311 7844
10312 7845
10313 RUNTIME_FUNCTION(Runtime_SystemBreak) {
10314 SealHandleScope shs(isolate);
10315 DCHECK(args.length() == 0);
10316 base::OS::DebugBreak();
10317 return isolate->heap()->undefined_value();
10318 }
10319
10320
10321 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) { 7846 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
10322 HandleScope scope(isolate); 7847 HandleScope scope(isolate);
10323 #ifdef DEBUG 7848 #ifdef DEBUG
10324 DCHECK(args.length() == 1); 7849 DCHECK(args.length() == 1);
10325 // Get the function and make sure it is compiled. 7850 // Get the function and make sure it is compiled.
10326 CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); 7851 CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
10327 if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) { 7852 if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
10328 return isolate->heap()->exception(); 7853 return isolate->heap()->exception();
10329 } 7854 }
10330 OFStream os(stdout); 7855 OFStream os(stdout);
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
10692 DebugScope debug_scope(isolate->debug()); 8217 DebugScope debug_scope(isolate->debug());
10693 maybe_result = Execution::Call(isolate, function, 8218 maybe_result = Execution::Call(isolate, function,
10694 handle(function->global_proxy()), 0, NULL); 8219 handle(function->global_proxy()), 0, NULL);
10695 } 8220 }
10696 Handle<Object> result; 8221 Handle<Object> result;
10697 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); 8222 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
10698 return *result; 8223 return *result;
10699 } 8224 }
10700 8225
10701 8226
10702 // Sets a v8 flag.
10703 RUNTIME_FUNCTION(Runtime_SetFlags) {
10704 SealHandleScope shs(isolate);
10705 DCHECK(args.length() == 1);
10706 CONVERT_ARG_CHECKED(String, arg, 0);
10707 SmartArrayPointer<char> flags =
10708 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
10709 FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
10710 return isolate->heap()->undefined_value();
10711 }
10712
10713
10714 // Performs a GC. 8227 // Performs a GC.
10715 // Presently, it only does a full GC. 8228 // Presently, it only does a full GC.
10716 RUNTIME_FUNCTION(Runtime_CollectGarbage) { 8229 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
10717 SealHandleScope shs(isolate); 8230 SealHandleScope shs(isolate);
10718 DCHECK(args.length() == 1); 8231 DCHECK(args.length() == 1);
10719 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage"); 8232 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
10720 return isolate->heap()->undefined_value(); 8233 return isolate->heap()->undefined_value();
10721 } 8234 }
10722 8235
10723 8236
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
10866 RUNTIME_ASSERT(0 <= offset && offset < code->Size()); 8379 RUNTIME_ASSERT(0 <= offset && offset < code->Size());
10867 Address pc = code->address() + offset; 8380 Address pc = code->address() + offset;
10868 8381
10869 return Smi::FromInt(code->SourcePosition(pc)); 8382 return Smi::FromInt(code->SourcePosition(pc));
10870 } 8383 }
10871 8384
10872 return isolate->heap()->undefined_value(); 8385 return isolate->heap()->undefined_value();
10873 } 8386 }
10874 8387
10875 8388
10876 RUNTIME_FUNCTION(Runtime_Abort) {
10877 SealHandleScope shs(isolate);
10878 DCHECK(args.length() == 1);
10879 CONVERT_SMI_ARG_CHECKED(message_id, 0);
10880 const char* message =
10881 GetBailoutReason(static_cast<BailoutReason>(message_id));
10882 base::OS::PrintError("abort: %s\n", message);
10883 isolate->PrintStack(stderr);
10884 base::OS::Abort();
10885 UNREACHABLE();
10886 return NULL;
10887 }
10888
10889
10890 RUNTIME_FUNCTION(Runtime_AbortJS) {
10891 HandleScope scope(isolate);
10892 DCHECK(args.length() == 1);
10893 CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
10894 base::OS::PrintError("abort: %s\n", message->ToCString().get());
10895 isolate->PrintStack(stderr);
10896 base::OS::Abort();
10897 UNREACHABLE();
10898 return NULL;
10899 }
10900
10901
10902 RUNTIME_FUNCTION(Runtime_FlattenString) {
10903 HandleScope scope(isolate);
10904 DCHECK(args.length() == 1);
10905 CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
10906 return *String::Flatten(str);
10907 }
10908
10909
10910 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
10911 HandleScope scope(isolate);
10912 DCHECK(args.length() == 0);
10913 isolate->heap()->NotifyContextDisposed();
10914 return isolate->heap()->undefined_value();
10915 }
10916
10917
10918 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { 8389 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
10919 HandleScope scope(isolate); 8390 HandleScope scope(isolate);
10920 DCHECK(args.length() == 2); 8391 DCHECK(args.length() == 2);
10921 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 8392 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10922 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); 8393 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
10923 RUNTIME_ASSERT((index->value() & 1) == 1); 8394 RUNTIME_ASSERT((index->value() & 1) == 1);
10924 FieldIndex field_index = 8395 FieldIndex field_index =
10925 FieldIndex::ForLoadByFieldIndex(object->map(), index->value()); 8396 FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
10926 if (field_index.is_inobject()) { 8397 if (field_index.is_inobject()) {
10927 RUNTIME_ASSERT(field_index.property_index() < 8398 RUNTIME_ASSERT(field_index.property_index() <
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
11107 } 8578 }
11108 #endif 8579 #endif
11109 8580
11110 8581
11111 RUNTIME_FUNCTION(Runtime_IS_VAR) { 8582 RUNTIME_FUNCTION(Runtime_IS_VAR) {
11112 UNREACHABLE(); // implemented as macro in the parser 8583 UNREACHABLE(); // implemented as macro in the parser
11113 return NULL; 8584 return NULL;
11114 } 8585 }
11115 8586
11116 8587
11117 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
11118 RUNTIME_FUNCTION(Runtime_Has##Name) { \
11119 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
11120 return isolate->heap()->ToBoolean(obj->Has##Name()); \
11121 }
11122
11123 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
11124 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
11125 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
11126 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
11127 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
11128 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
11129 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
11130 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
11131 // Properties test sitting with elements tests - not fooling anyone.
11132 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
11133
11134 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
11135
11136
11137 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \ 8588 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
11138 RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \ 8589 RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \
11139 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ 8590 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
11140 return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \ 8591 return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \
11141 } 8592 }
11142 8593
11143 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) 8594 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
11144 8595
11145 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION 8596 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
11146 8597
11147 8598
11148 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \ 8599 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
11149 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \ 8600 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \
11150 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ 8601 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
11151 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \ 8602 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
11152 } 8603 }
11153 8604
11154 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) 8605 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
11155 8606
11156 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION 8607 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
11157 8608
11158 8609
11159 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
11160 SealHandleScope shs(isolate);
11161 DCHECK(args.length() == 2);
11162 CONVERT_ARG_CHECKED(JSObject, obj1, 0);
11163 CONVERT_ARG_CHECKED(JSObject, obj2, 1);
11164 return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
11165 }
11166
11167
11168 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { 8610 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
11169 SealHandleScope shs(isolate); 8611 SealHandleScope shs(isolate);
11170 DCHECK(args.length() == 1); 8612 DCHECK(args.length() == 1);
11171 CONVERT_ARG_CHECKED(Object, obj, 0); 8613 CONVERT_ARG_CHECKED(Object, obj, 0);
11172 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); 8614 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
11173 } 8615 }
11174 8616
11175 8617
11176 RUNTIME_FUNCTION(Runtime_IsObserved) { 8618 RUNTIME_FUNCTION(Runtime_IsObserved) {
11177 SealHandleScope shs(isolate); 8619 SealHandleScope shs(isolate);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
11215 } 8657 }
11216 8658
11217 8659
11218 RUNTIME_FUNCTION(Runtime_GetObservationState) { 8660 RUNTIME_FUNCTION(Runtime_GetObservationState) {
11219 SealHandleScope shs(isolate); 8661 SealHandleScope shs(isolate);
11220 DCHECK(args.length() == 0); 8662 DCHECK(args.length() == 0);
11221 return isolate->heap()->observation_state(); 8663 return isolate->heap()->observation_state();
11222 } 8664 }
11223 8665
11224 8666
11225 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
11226 HandleScope scope(isolate);
11227 DCHECK(args.length() == 0);
11228 // TODO(adamk): Currently this runtime function is only called three times per
11229 // isolate. If it's called more often, the map should be moved into the
11230 // strong root list.
11231 Handle<Map> map =
11232 isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
11233 Handle<JSWeakMap> weakmap =
11234 Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
11235 return *WeakCollectionInitialize(isolate, weakmap);
11236 }
11237
11238
11239 static bool ContextsHaveSameOrigin(Handle<Context> context1, 8667 static bool ContextsHaveSameOrigin(Handle<Context> context1,
11240 Handle<Context> context2) { 8668 Handle<Context> context2) {
11241 return context1->security_token() == context2->security_token(); 8669 return context1->security_token() == context2->security_token();
11242 } 8670 }
11243 8671
11244 8672
11245 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) { 8673 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
11246 HandleScope scope(isolate); 8674 HandleScope scope(isolate);
11247 DCHECK(args.length() == 3); 8675 DCHECK(args.length() == 3);
11248 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); 8676 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
11694 9122
11695 9123
11696 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) { 9124 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
11697 SealHandleScope shs(isolate); 9125 SealHandleScope shs(isolate);
11698 DCHECK(args.length() == 1); 9126 DCHECK(args.length() == 1);
11699 CONVERT_ARG_CHECKED(Object, obj, 0); 9127 CONVERT_ARG_CHECKED(Object, obj, 0);
11700 return isolate->heap()->ToBoolean(obj->IsSpecObject()); 9128 return isolate->heap()->ToBoolean(obj->IsSpecObject());
11701 } 9129 }
11702 9130
11703 9131
11704 RUNTIME_FUNCTION(RuntimeReference_MathPow) {
11705 SealHandleScope shs(isolate);
11706 return __RT_impl_Runtime_MathPowSlow(args, isolate);
11707 }
11708
11709
11710 RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
11711 SealHandleScope shs(isolate);
11712 DCHECK(args.length() == 1);
11713 CONVERT_ARG_CHECKED(Object, obj, 0);
11714 if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
11715 HeapNumber* number = HeapNumber::cast(obj);
11716 return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
11717 }
11718
11719
11720 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) { 9132 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
11721 SealHandleScope shs(isolate); 9133 SealHandleScope shs(isolate);
11722 DCHECK(args.length() == 1); 9134 DCHECK(args.length() == 1);
11723 return isolate->heap()->false_value(); 9135 return isolate->heap()->false_value();
11724 } 9136 }
11725 9137
11726 9138
11727 RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) { 9139 RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
11728 SealHandleScope shs(isolate); 9140 SealHandleScope shs(isolate);
11729 DCHECK(args.length() == 1); 9141 DCHECK(args.length() == 1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
11761 9173
11762 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) { 9174 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
11763 HandleScope scope(isolate); 9175 HandleScope scope(isolate);
11764 DCHECK(args.length() == 2); 9176 DCHECK(args.length() == 2);
11765 CONVERT_SMI_ARG_CHECKED(id, 0); 9177 CONVERT_SMI_ARG_CHECKED(id, 0);
11766 args[0] = isolate->native_context()->jsfunction_result_caches()->get(id); 9178 args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
11767 return __RT_impl_Runtime_GetFromCache(args, isolate); 9179 return __RT_impl_Runtime_GetFromCache(args, isolate);
11768 } 9180 }
11769 9181
11770 9182
11771 RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
11772 SealHandleScope shs(isolate);
11773 return __RT_impl_Runtime_NumberToStringRT(args, isolate);
11774 }
11775
11776
11777 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) { 9183 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
11778 SealHandleScope shs(isolate); 9184 SealHandleScope shs(isolate);
11779 return Smi::FromInt(isolate->debug()->is_active()); 9185 return Smi::FromInt(isolate->debug()->is_active());
11780 } 9186 }
11781 9187
11782 9188
11783 // ---------------------------------------------------------------------------- 9189 // ----------------------------------------------------------------------------
11784 // Implementation of Runtime 9190 // Implementation of Runtime
11785 9191
11786 #define F(name, number_of_args, result_size) \ 9192 #define F(name, number_of_args, result_size) \
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
11853 } 9259 }
11854 return NULL; 9260 return NULL;
11855 } 9261 }
11856 9262
11857 9263
11858 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 9264 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
11859 return &(kIntrinsicFunctions[static_cast<int>(id)]); 9265 return &(kIntrinsicFunctions[static_cast<int>(id)]);
11860 } 9266 }
11861 } 9267 }
11862 } // namespace v8::internal 9268 } // namespace v8::internal
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/runtime/runtime-collections.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698