| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 | 643 |
| 644 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { | 644 RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { |
| 645 SealHandleScope shs(isolate); | 645 SealHandleScope shs(isolate); |
| 646 ASSERT(args.length() == 1); | 646 ASSERT(args.length() == 1); |
| 647 CONVERT_ARG_CHECKED(JSProxy, proxy, 0); | 647 CONVERT_ARG_CHECKED(JSProxy, proxy, 0); |
| 648 proxy->Fix(); | 648 proxy->Fix(); |
| 649 return isolate->heap()->undefined_value(); | 649 return isolate->heap()->undefined_value(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 | 652 |
| 653 static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, | 653 void Runtime::FreeArrayBuffer(Isolate* isolate, |
| 654 Persistent<Value>* object, | 654 JSArrayBuffer* phantom_array_buffer) { |
| 655 void* data) { | 655 if (phantom_array_buffer->is_external()) return; |
| 656 Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); | |
| 657 HandleScope scope(isolate); | |
| 658 Handle<Object> internal_object = Utils::OpenPersistent(object); | |
| 659 Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(*internal_object)); | |
| 660 | 656 |
| 661 if (!array_buffer->is_external()) { | 657 size_t allocated_length = NumberToSize( |
| 662 size_t allocated_length = NumberToSize( | 658 isolate, phantom_array_buffer->byte_length()); |
| 663 isolate, array_buffer->byte_length()); | 659 |
| 664 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( | 660 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( |
| 665 -static_cast<intptr_t>(allocated_length)); | 661 -static_cast<intptr_t>(allocated_length)); |
| 666 CHECK(V8::ArrayBufferAllocator() != NULL); | 662 CHECK(V8::ArrayBufferAllocator() != NULL); |
| 667 V8::ArrayBufferAllocator()->Free(data); | 663 V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store()); |
| 668 } | |
| 669 object->Dispose(external_isolate); | |
| 670 } | 664 } |
| 671 | 665 |
| 672 | 666 |
| 673 void Runtime::SetupArrayBuffer(Isolate* isolate, | 667 void Runtime::SetupArrayBuffer(Isolate* isolate, |
| 674 Handle<JSArrayBuffer> array_buffer, | 668 Handle<JSArrayBuffer> array_buffer, |
| 675 bool is_external, | 669 bool is_external, |
| 676 void* data, | 670 void* data, |
| 677 size_t allocated_length) { | 671 size_t allocated_length) { |
| 678 ASSERT(array_buffer->GetInternalFieldCount() == | 672 ASSERT(array_buffer->GetInternalFieldCount() == |
| 679 v8::ArrayBuffer::kInternalFieldCount); | 673 v8::ArrayBuffer::kInternalFieldCount); |
| 680 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { | 674 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { |
| 681 array_buffer->SetInternalField(i, Smi::FromInt(0)); | 675 array_buffer->SetInternalField(i, Smi::FromInt(0)); |
| 682 } | 676 } |
| 683 array_buffer->set_backing_store(data); | 677 array_buffer->set_backing_store(data); |
| 684 array_buffer->set_flag(Smi::FromInt(0)); | 678 array_buffer->set_flag(Smi::FromInt(0)); |
| 685 array_buffer->set_is_external(is_external); | 679 array_buffer->set_is_external(is_external); |
| 686 | 680 |
| 687 Handle<Object> byte_length = | 681 Handle<Object> byte_length = |
| 688 isolate->factory()->NewNumberFromSize(allocated_length); | 682 isolate->factory()->NewNumberFromSize(allocated_length); |
| 689 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); | 683 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); |
| 690 array_buffer->set_byte_length(*byte_length); | 684 array_buffer->set_byte_length(*byte_length); |
| 691 | 685 |
| 692 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); | 686 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); |
| 693 isolate->heap()->set_array_buffers_list(*array_buffer); | 687 isolate->heap()->set_array_buffers_list(*array_buffer); |
| 694 array_buffer->set_weak_first_array(isolate->heap()->undefined_value()); | 688 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); |
| 695 } | 689 } |
| 696 | 690 |
| 697 | 691 |
| 698 bool Runtime::SetupArrayBufferAllocatingData( | 692 bool Runtime::SetupArrayBufferAllocatingData( |
| 699 Isolate* isolate, | 693 Isolate* isolate, |
| 700 Handle<JSArrayBuffer> array_buffer, | 694 Handle<JSArrayBuffer> array_buffer, |
| 701 size_t allocated_length) { | 695 size_t allocated_length) { |
| 702 void* data; | 696 void* data; |
| 703 CHECK(V8::ArrayBufferAllocator() != NULL); | 697 CHECK(V8::ArrayBufferAllocator() != NULL); |
| 704 if (allocated_length != 0) { | 698 if (allocated_length != 0) { |
| 705 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); | 699 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); |
| 706 if (data == NULL) return false; | 700 if (data == NULL) return false; |
| 707 memset(data, 0, allocated_length); | 701 memset(data, 0, allocated_length); |
| 708 } else { | 702 } else { |
| 709 data = NULL; | 703 data = NULL; |
| 710 } | 704 } |
| 711 | 705 |
| 712 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); | 706 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); |
| 713 | 707 |
| 714 Handle<Object> persistent = isolate->global_handles()->Create(*array_buffer); | |
| 715 GlobalHandles::MakeWeak(persistent.location(), data, ArrayBufferWeakCallback); | |
| 716 GlobalHandles::MarkIndependent(persistent.location()); | |
| 717 | |
| 718 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); | 708 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); |
| 719 | 709 |
| 720 return true; | 710 return true; |
| 721 } | 711 } |
| 722 | 712 |
| 723 | 713 |
| 724 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { | 714 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { |
| 725 HandleScope scope(isolate); | 715 HandleScope scope(isolate); |
| 726 ASSERT(args.length() == 2); | 716 ASSERT(args.length() == 2); |
| 727 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); | 717 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 holder->set_byte_offset(*byte_offset_object); | 843 holder->set_byte_offset(*byte_offset_object); |
| 854 holder->set_byte_length(*byte_length_object); | 844 holder->set_byte_length(*byte_length_object); |
| 855 | 845 |
| 856 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); | 846 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); |
| 857 size_t byte_length = NumberToSize(isolate, *byte_length_object); | 847 size_t byte_length = NumberToSize(isolate, *byte_length_object); |
| 858 ASSERT(byte_length % elementSize == 0); | 848 ASSERT(byte_length % elementSize == 0); |
| 859 size_t length = byte_length / elementSize; | 849 size_t length = byte_length / elementSize; |
| 860 | 850 |
| 861 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | 851 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); |
| 862 holder->set_length(*length_obj); | 852 holder->set_length(*length_obj); |
| 863 holder->set_weak_next(buffer->weak_first_array()); | 853 holder->set_weak_next(buffer->weak_first_view()); |
| 864 buffer->set_weak_first_array(*holder); | 854 buffer->set_weak_first_view(*holder); |
| 865 | 855 |
| 866 Handle<ExternalArray> elements = | 856 Handle<ExternalArray> elements = |
| 867 isolate->factory()->NewExternalArray( | 857 isolate->factory()->NewExternalArray( |
| 868 static_cast<int>(length), arrayType, | 858 static_cast<int>(length), arrayType, |
| 869 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | 859 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
| 870 holder->set_elements(*elements); | 860 holder->set_elements(*elements); |
| 871 return isolate->heap()->undefined_value(); | 861 return isolate->heap()->undefined_value(); |
| 872 } | 862 } |
| 873 | 863 |
| 874 | 864 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 JSObject::SetElement( | 996 JSObject::SetElement( |
| 1007 target, static_cast<uint32_t>(offset + idx), value, | 997 target, static_cast<uint32_t>(offset + idx), value, |
| 1008 NONE, kNonStrictMode); | 998 NONE, kNonStrictMode); |
| 1009 } | 999 } |
| 1010 } | 1000 } |
| 1011 | 1001 |
| 1012 return isolate->heap()->true_value(); | 1002 return isolate->heap()->true_value(); |
| 1013 } | 1003 } |
| 1014 | 1004 |
| 1015 | 1005 |
| 1006 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) { |
| 1007 HandleScope scope(isolate); |
| 1008 ASSERT(args.length() == 4); |
| 1009 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); |
| 1010 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); |
| 1011 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2); |
| 1012 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3); |
| 1013 |
| 1014 holder->set_buffer(*buffer); |
| 1015 ASSERT(byte_offset->IsNumber()); |
| 1016 ASSERT( |
| 1017 NumberToSize(isolate, buffer->byte_length()) >= |
| 1018 NumberToSize(isolate, *byte_offset) |
| 1019 + NumberToSize(isolate, *byte_length)); |
| 1020 holder->set_byte_offset(*byte_offset); |
| 1021 ASSERT(byte_length->IsNumber()); |
| 1022 holder->set_byte_length(*byte_length); |
| 1023 |
| 1024 holder->set_weak_next(buffer->weak_first_view()); |
| 1025 buffer->set_weak_first_view(*holder); |
| 1026 |
| 1027 return isolate->heap()->undefined_value(); |
| 1028 } |
| 1029 |
| 1030 |
| 1031 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) { |
| 1032 HandleScope scope(isolate); |
| 1033 ASSERT(args.length() == 1); |
| 1034 CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0); |
| 1035 return data_view->buffer(); |
| 1036 } |
| 1037 |
| 1038 |
| 1039 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) { |
| 1040 HandleScope scope(isolate); |
| 1041 ASSERT(args.length() == 1); |
| 1042 CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0); |
| 1043 return data_view->byte_offset(); |
| 1044 } |
| 1045 |
| 1046 |
| 1047 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) { |
| 1048 HandleScope scope(isolate); |
| 1049 ASSERT(args.length() == 1); |
| 1050 CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0); |
| 1051 return data_view->byte_length(); |
| 1052 } |
| 1053 |
| 1054 |
| 1055 inline static bool NeedToFlipBytes(bool is_little_endian) { |
| 1056 #ifdef V8_TARGET_LITTLE_ENDIAN |
| 1057 return !is_little_endian; |
| 1058 #else |
| 1059 return is_little_endian; |
| 1060 #endif |
| 1061 } |
| 1062 |
| 1063 |
| 1064 template<int n> |
| 1065 inline void CopyBytes(uint8_t* target, uint8_t* source) { |
| 1066 for (int i = 0; i < n; i++) { |
| 1067 *(target++) = *(source++); |
| 1068 } |
| 1069 } |
| 1070 |
| 1071 |
| 1072 template<int n> |
| 1073 inline void FlipBytes(uint8_t* target, uint8_t* source) { |
| 1074 source = source + (n-1); |
| 1075 for (int i = 0; i < n; i++) { |
| 1076 *(target++) = *(source--); |
| 1077 } |
| 1078 } |
| 1079 |
| 1080 |
| 1081 template<typename T> |
| 1082 inline static bool DataViewGetValue( |
| 1083 Isolate* isolate, |
| 1084 Handle<JSDataView> data_view, |
| 1085 Handle<Object> byte_offset_obj, |
| 1086 bool is_little_endian, |
| 1087 T* result) { |
| 1088 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); |
| 1089 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); |
| 1090 |
| 1091 size_t data_view_byte_offset = |
| 1092 NumberToSize(isolate, data_view->byte_offset()); |
| 1093 size_t data_view_byte_length = |
| 1094 NumberToSize(isolate, data_view->byte_length()); |
| 1095 if (byte_offset + sizeof(T) > data_view_byte_length || |
| 1096 byte_offset + sizeof(T) < byte_offset) { // overflow |
| 1097 return false; |
| 1098 } |
| 1099 |
| 1100 union Value { |
| 1101 T data; |
| 1102 uint8_t bytes[sizeof(T)]; |
| 1103 }; |
| 1104 |
| 1105 Value value; |
| 1106 size_t buffer_offset = data_view_byte_offset + byte_offset; |
| 1107 ASSERT( |
| 1108 NumberToSize(isolate, buffer->byte_length()) |
| 1109 >= buffer_offset + sizeof(T)); |
| 1110 uint8_t* source = |
| 1111 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; |
| 1112 if (NeedToFlipBytes(is_little_endian)) { |
| 1113 FlipBytes<sizeof(T)>(value.bytes, source); |
| 1114 } else { |
| 1115 CopyBytes<sizeof(T)>(value.bytes, source); |
| 1116 } |
| 1117 *result = value.data; |
| 1118 return true; |
| 1119 } |
| 1120 |
| 1121 |
| 1122 template<typename T> |
| 1123 static bool DataViewSetValue( |
| 1124 Isolate* isolate, |
| 1125 Handle<JSDataView> data_view, |
| 1126 Handle<Object> byte_offset_obj, |
| 1127 bool is_little_endian, |
| 1128 T data) { |
| 1129 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); |
| 1130 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); |
| 1131 |
| 1132 size_t data_view_byte_offset = |
| 1133 NumberToSize(isolate, data_view->byte_offset()); |
| 1134 size_t data_view_byte_length = |
| 1135 NumberToSize(isolate, data_view->byte_length()); |
| 1136 if (byte_offset + sizeof(T) > data_view_byte_length || |
| 1137 byte_offset + sizeof(T) < byte_offset) { // overflow |
| 1138 return false; |
| 1139 } |
| 1140 |
| 1141 union Value { |
| 1142 T data; |
| 1143 uint8_t bytes[sizeof(T)]; |
| 1144 }; |
| 1145 |
| 1146 Value value; |
| 1147 value.data = data; |
| 1148 size_t buffer_offset = data_view_byte_offset + byte_offset; |
| 1149 ASSERT( |
| 1150 NumberToSize(isolate, buffer->byte_length()) |
| 1151 >= buffer_offset + sizeof(T)); |
| 1152 uint8_t* target = |
| 1153 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; |
| 1154 if (NeedToFlipBytes(is_little_endian)) { |
| 1155 FlipBytes<sizeof(T)>(target, value.bytes); |
| 1156 } else { |
| 1157 CopyBytes<sizeof(T)>(target, value.bytes); |
| 1158 } |
| 1159 return true; |
| 1160 } |
| 1161 |
| 1162 |
| 1163 #define DATA_VIEW_GETTER(TypeName, Type, Converter) \ |
| 1164 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) { \ |
| 1165 HandleScope scope(isolate); \ |
| 1166 ASSERT(args.length() == 3); \ |
| 1167 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ |
| 1168 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ |
| 1169 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \ |
| 1170 Type result; \ |
| 1171 if (DataViewGetValue( \ |
| 1172 isolate, holder, offset, is_little_endian, &result)) { \ |
| 1173 return isolate->heap()->Converter(result); \ |
| 1174 } else { \ |
| 1175 return isolate->Throw(*isolate->factory()->NewRangeError( \ |
| 1176 "invalid_data_view_accessor_offset", \ |
| 1177 HandleVector<Object>(NULL, 0))); \ |
| 1178 } \ |
| 1179 } |
| 1180 |
| 1181 DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32) |
| 1182 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32) |
| 1183 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32) |
| 1184 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32) |
| 1185 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32) |
| 1186 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32) |
| 1187 DATA_VIEW_GETTER(Float32, float, NumberFromDouble) |
| 1188 DATA_VIEW_GETTER(Float64, double, NumberFromDouble) |
| 1189 |
| 1190 #undef DATA_VIEW_GETTER |
| 1191 |
| 1192 #define DATA_VIEW_SETTER(TypeName, Type) \ |
| 1193 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \ |
| 1194 HandleScope scope(isolate); \ |
| 1195 ASSERT(args.length() == 4); \ |
| 1196 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ |
| 1197 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ |
| 1198 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \ |
| 1199 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ |
| 1200 Type v = static_cast<Type>(value->Number()); \ |
| 1201 if (DataViewSetValue( \ |
| 1202 isolate, holder, offset, is_little_endian, v)) { \ |
| 1203 return isolate->heap()->undefined_value(); \ |
| 1204 } else { \ |
| 1205 return isolate->Throw(*isolate->factory()->NewRangeError( \ |
| 1206 "invalid_data_view_accessor_offset", \ |
| 1207 HandleVector<Object>(NULL, 0))); \ |
| 1208 } \ |
| 1209 } |
| 1210 |
| 1211 DATA_VIEW_SETTER(Uint8, uint8_t) |
| 1212 DATA_VIEW_SETTER(Int8, int8_t) |
| 1213 DATA_VIEW_SETTER(Uint16, uint16_t) |
| 1214 DATA_VIEW_SETTER(Int16, int16_t) |
| 1215 DATA_VIEW_SETTER(Uint32, uint32_t) |
| 1216 DATA_VIEW_SETTER(Int32, int32_t) |
| 1217 DATA_VIEW_SETTER(Float32, float) |
| 1218 DATA_VIEW_SETTER(Float64, double) |
| 1219 |
| 1220 #undef DATA_VIEW_SETTER |
| 1221 |
| 1222 |
| 1016 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { | 1223 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { |
| 1017 HandleScope scope(isolate); | 1224 HandleScope scope(isolate); |
| 1018 ASSERT(args.length() == 1); | 1225 ASSERT(args.length() == 1); |
| 1019 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); | 1226 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); |
| 1020 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); | 1227 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
| 1021 holder->set_table(*table); | 1228 holder->set_table(*table); |
| 1022 return *holder; | 1229 return *holder; |
| 1023 } | 1230 } |
| 1024 | 1231 |
| 1025 | 1232 |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 } | 1693 } |
| 1487 | 1694 |
| 1488 | 1695 |
| 1489 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) { | 1696 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpCompile) { |
| 1490 HandleScope scope(isolate); | 1697 HandleScope scope(isolate); |
| 1491 ASSERT(args.length() == 3); | 1698 ASSERT(args.length() == 3); |
| 1492 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); | 1699 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); |
| 1493 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); | 1700 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); |
| 1494 CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); | 1701 CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); |
| 1495 Handle<Object> result = | 1702 Handle<Object> result = |
| 1496 RegExpImpl::Compile(re, pattern, flags, isolate->runtime_zone()); | 1703 RegExpImpl::Compile(re, pattern, flags); |
| 1497 if (result.is_null()) return Failure::Exception(); | 1704 if (result.is_null()) return Failure::Exception(); |
| 1498 return *result; | 1705 return *result; |
| 1499 } | 1706 } |
| 1500 | 1707 |
| 1501 | 1708 |
| 1502 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) { | 1709 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateApiFunction) { |
| 1503 HandleScope scope(isolate); | 1710 HandleScope scope(isolate); |
| 1504 ASSERT(args.length() == 1); | 1711 ASSERT(args.length() == 1); |
| 1505 CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0); | 1712 CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0); |
| 1506 return *isolate->factory()->CreateApiFunction(data); | 1713 return *isolate->factory()->CreateApiFunction(data); |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2586 } | 2793 } |
| 2587 | 2794 |
| 2588 | 2795 |
| 2589 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { | 2796 RUNTIME_FUNCTION(MaybeObject*, Runtime_SuspendJSGeneratorObject) { |
| 2590 SealHandleScope shs(isolate); | 2797 SealHandleScope shs(isolate); |
| 2591 ASSERT(args.length() == 1); | 2798 ASSERT(args.length() == 1); |
| 2592 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); | 2799 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0); |
| 2593 | 2800 |
| 2594 JavaScriptFrameIterator stack_iterator(isolate); | 2801 JavaScriptFrameIterator stack_iterator(isolate); |
| 2595 JavaScriptFrame* frame = stack_iterator.frame(); | 2802 JavaScriptFrame* frame = stack_iterator.frame(); |
| 2596 JSFunction* function = JSFunction::cast(frame->function()); | 2803 RUNTIME_ASSERT(JSFunction::cast(frame->function())->shared()->is_generator()); |
| 2597 RUNTIME_ASSERT(function->shared()->is_generator()); | 2804 ASSERT_EQ(JSFunction::cast(frame->function()), generator_object->function()); |
| 2598 ASSERT_EQ(function, generator_object->function()); | 2805 |
| 2806 // The caller should have saved the context and continuation already. |
| 2807 ASSERT_EQ(generator_object->context(), Context::cast(frame->context())); |
| 2808 ASSERT_LT(0, generator_object->continuation()); |
| 2599 | 2809 |
| 2600 // We expect there to be at least two values on the operand stack: the return | 2810 // We expect there to be at least two values on the operand stack: the return |
| 2601 // value of the yield expression, and the argument to this runtime call. | 2811 // value of the yield expression, and the argument to this runtime call. |
| 2602 // Neither of those should be saved. | 2812 // Neither of those should be saved. |
| 2603 int operands_count = frame->ComputeOperandsCount(); | 2813 int operands_count = frame->ComputeOperandsCount(); |
| 2604 ASSERT(operands_count >= 2); | 2814 ASSERT_GE(operands_count, 2); |
| 2605 operands_count -= 2; | 2815 operands_count -= 2; |
| 2606 | 2816 |
| 2607 if (operands_count == 0) { | 2817 if (operands_count == 0) { |
| 2818 // Although it's semantically harmless to call this function with an |
| 2819 // operands_count of zero, it is also unnecessary. |
| 2608 ASSERT_EQ(generator_object->operand_stack(), | 2820 ASSERT_EQ(generator_object->operand_stack(), |
| 2609 isolate->heap()->empty_fixed_array()); | 2821 isolate->heap()->empty_fixed_array()); |
| 2610 ASSERT_EQ(generator_object->stack_handler_index(), -1); | 2822 ASSERT_EQ(generator_object->stack_handler_index(), -1); |
| 2611 // If there are no operands on the stack, there shouldn't be a handler | 2823 // If there are no operands on the stack, there shouldn't be a handler |
| 2612 // active either. | 2824 // active either. |
| 2613 ASSERT(!frame->HasHandler()); | 2825 ASSERT(!frame->HasHandler()); |
| 2614 } else { | 2826 } else { |
| 2615 int stack_handler_index = -1; | 2827 int stack_handler_index = -1; |
| 2616 MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count); | 2828 MaybeObject* alloc = isolate->heap()->AllocateFixedArray(operands_count); |
| 2617 FixedArray* operand_stack; | 2829 FixedArray* operand_stack; |
| 2618 if (!alloc->To(&operand_stack)) return alloc; | 2830 if (!alloc->To(&operand_stack)) return alloc; |
| 2619 frame->SaveOperandStack(operand_stack, &stack_handler_index); | 2831 frame->SaveOperandStack(operand_stack, &stack_handler_index); |
| 2620 generator_object->set_operand_stack(operand_stack); | 2832 generator_object->set_operand_stack(operand_stack); |
| 2621 generator_object->set_stack_handler_index(stack_handler_index); | 2833 generator_object->set_stack_handler_index(stack_handler_index); |
| 2622 } | 2834 } |
| 2623 | 2835 |
| 2624 // Set continuation down here to avoid side effects if the operand stack | 2836 return isolate->heap()->undefined_value(); |
| 2625 // allocation fails. | |
| 2626 intptr_t offset = frame->pc() - function->code()->instruction_start(); | |
| 2627 ASSERT(offset > 0 && Smi::IsValid(offset)); | |
| 2628 generator_object->set_continuation(static_cast<int>(offset)); | |
| 2629 | |
| 2630 // It's possible for the context to be other than the initial context even if | |
| 2631 // there is no stack handler active. For example, this is the case in the | |
| 2632 // body of a "with" statement. Therefore we always save the context. | |
| 2633 generator_object->set_context(Context::cast(frame->context())); | |
| 2634 | |
| 2635 // The return value is the hole for a suspend return, and anything else for a | |
| 2636 // resume return. | |
| 2637 return isolate->heap()->the_hole_value(); | |
| 2638 } | 2837 } |
| 2639 | 2838 |
| 2640 | 2839 |
| 2641 // Note that this function is the slow path for resuming generators. It is only | 2840 // Note that this function is the slow path for resuming generators. It is only |
| 2642 // called if the suspended activation had operands on the stack, stack handlers | 2841 // called if the suspended activation had operands on the stack, stack handlers |
| 2643 // needing rewinding, or if the resume should throw an exception. The fast path | 2842 // needing rewinding, or if the resume should throw an exception. The fast path |
| 2644 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is | 2843 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is |
| 2645 // inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is | 2844 // inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is |
| 2646 // called in any case, as it needs to reconstruct the stack frame and make space | 2845 // called in any case, as it needs to reconstruct the stack frame and make space |
| 2647 // for arguments and operands. | 2846 // for arguments and operands. |
| (...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3394 template<typename ResultSeqString> | 3593 template<typename ResultSeqString> |
| 3395 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( | 3594 MUST_USE_RESULT static MaybeObject* StringReplaceGlobalAtomRegExpWithString( |
| 3396 Isolate* isolate, | 3595 Isolate* isolate, |
| 3397 Handle<String> subject, | 3596 Handle<String> subject, |
| 3398 Handle<JSRegExp> pattern_regexp, | 3597 Handle<JSRegExp> pattern_regexp, |
| 3399 Handle<String> replacement, | 3598 Handle<String> replacement, |
| 3400 Handle<JSArray> last_match_info) { | 3599 Handle<JSArray> last_match_info) { |
| 3401 ASSERT(subject->IsFlat()); | 3600 ASSERT(subject->IsFlat()); |
| 3402 ASSERT(replacement->IsFlat()); | 3601 ASSERT(replacement->IsFlat()); |
| 3403 | 3602 |
| 3404 Zone* zone = isolate->runtime_zone(); | 3603 Zone zone(isolate); |
| 3405 ZoneScope zone_space(zone, DELETE_ON_EXIT); | 3604 ZoneList<int> indices(8, &zone); |
| 3406 ZoneList<int> indices(8, zone); | |
| 3407 ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); | 3605 ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); |
| 3408 String* pattern = | 3606 String* pattern = |
| 3409 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 3607 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
| 3410 int subject_len = subject->length(); | 3608 int subject_len = subject->length(); |
| 3411 int pattern_len = pattern->length(); | 3609 int pattern_len = pattern->length(); |
| 3412 int replacement_len = replacement->length(); | 3610 int replacement_len = replacement->length(); |
| 3413 | 3611 |
| 3414 FindStringIndicesDispatch( | 3612 FindStringIndicesDispatch( |
| 3415 isolate, *subject, pattern, &indices, 0xffffffff, zone); | 3613 isolate, *subject, pattern, &indices, 0xffffffff, &zone); |
| 3416 | 3614 |
| 3417 int matches = indices.length(); | 3615 int matches = indices.length(); |
| 3418 if (matches == 0) return *subject; | 3616 if (matches == 0) return *subject; |
| 3419 | 3617 |
| 3420 // Detect integer overflow. | 3618 // Detect integer overflow. |
| 3421 int64_t result_len_64 = | 3619 int64_t result_len_64 = |
| 3422 (static_cast<int64_t>(replacement_len) - | 3620 (static_cast<int64_t>(replacement_len) - |
| 3423 static_cast<int64_t>(pattern_len)) * | 3621 static_cast<int64_t>(pattern_len)) * |
| 3424 static_cast<int64_t>(matches) + | 3622 static_cast<int64_t>(matches) + |
| 3425 static_cast<int64_t>(subject_len); | 3623 static_cast<int64_t>(subject_len); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3481 Handle<JSRegExp> regexp, | 3679 Handle<JSRegExp> regexp, |
| 3482 Handle<String> replacement, | 3680 Handle<String> replacement, |
| 3483 Handle<JSArray> last_match_info) { | 3681 Handle<JSArray> last_match_info) { |
| 3484 ASSERT(subject->IsFlat()); | 3682 ASSERT(subject->IsFlat()); |
| 3485 ASSERT(replacement->IsFlat()); | 3683 ASSERT(replacement->IsFlat()); |
| 3486 | 3684 |
| 3487 int capture_count = regexp->CaptureCount(); | 3685 int capture_count = regexp->CaptureCount(); |
| 3488 int subject_length = subject->length(); | 3686 int subject_length = subject->length(); |
| 3489 | 3687 |
| 3490 // CompiledReplacement uses zone allocation. | 3688 // CompiledReplacement uses zone allocation. |
| 3491 Zone* zone = isolate->runtime_zone(); | 3689 Zone zone(isolate); |
| 3492 ZoneScope zonescope(zone, DELETE_ON_EXIT); | 3690 CompiledReplacement compiled_replacement(&zone); |
| 3493 CompiledReplacement compiled_replacement(zone); | |
| 3494 bool simple_replace = compiled_replacement.Compile(replacement, | 3691 bool simple_replace = compiled_replacement.Compile(replacement, |
| 3495 capture_count, | 3692 capture_count, |
| 3496 subject_length); | 3693 subject_length); |
| 3497 | 3694 |
| 3498 // Shortcut for simple non-regexp global replacements | 3695 // Shortcut for simple non-regexp global replacements |
| 3499 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { | 3696 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { |
| 3500 if (subject->HasOnlyOneByteChars() && | 3697 if (subject->HasOnlyOneByteChars() && |
| 3501 replacement->HasOnlyOneByteChars()) { | 3698 replacement->HasOnlyOneByteChars()) { |
| 3502 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 3699 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
| 3503 isolate, subject, regexp, replacement, last_match_info); | 3700 isolate, subject, regexp, replacement, last_match_info); |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4016 | 4213 |
| 4017 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 4214 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
| 4018 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); | 4215 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); |
| 4019 CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2); | 4216 CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2); |
| 4020 | 4217 |
| 4021 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); | 4218 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
| 4022 if (global_cache.HasException()) return Failure::Exception(); | 4219 if (global_cache.HasException()) return Failure::Exception(); |
| 4023 | 4220 |
| 4024 int capture_count = regexp->CaptureCount(); | 4221 int capture_count = regexp->CaptureCount(); |
| 4025 | 4222 |
| 4026 Zone* zone = isolate->runtime_zone(); | 4223 Zone zone(isolate); |
| 4027 ZoneScope zone_space(zone, DELETE_ON_EXIT); | 4224 ZoneList<int> offsets(8, &zone); |
| 4028 ZoneList<int> offsets(8, zone); | |
| 4029 | 4225 |
| 4030 while (true) { | 4226 while (true) { |
| 4031 int32_t* match = global_cache.FetchNext(); | 4227 int32_t* match = global_cache.FetchNext(); |
| 4032 if (match == NULL) break; | 4228 if (match == NULL) break; |
| 4033 offsets.Add(match[0], zone); // start | 4229 offsets.Add(match[0], &zone); // start |
| 4034 offsets.Add(match[1], zone); // end | 4230 offsets.Add(match[1], &zone); // end |
| 4035 } | 4231 } |
| 4036 | 4232 |
| 4037 if (global_cache.HasException()) return Failure::Exception(); | 4233 if (global_cache.HasException()) return Failure::Exception(); |
| 4038 | 4234 |
| 4039 if (offsets.length() == 0) { | 4235 if (offsets.length() == 0) { |
| 4040 // Not a single match. | 4236 // Not a single match. |
| 4041 return isolate->heap()->null_value(); | 4237 return isolate->heap()->null_value(); |
| 4042 } | 4238 } |
| 4043 | 4239 |
| 4044 RegExpImpl::SetLastMatchInfo(regexp_info, | 4240 RegExpImpl::SetLastMatchInfo(regexp_info, |
| (...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6109 } | 6305 } |
| 6110 | 6306 |
| 6111 // The limit can be very large (0xffffffffu), but since the pattern | 6307 // The limit can be very large (0xffffffffu), but since the pattern |
| 6112 // isn't empty, we can never create more parts than ~half the length | 6308 // isn't empty, we can never create more parts than ~half the length |
| 6113 // of the subject. | 6309 // of the subject. |
| 6114 | 6310 |
| 6115 if (!subject->IsFlat()) FlattenString(subject); | 6311 if (!subject->IsFlat()) FlattenString(subject); |
| 6116 | 6312 |
| 6117 static const int kMaxInitialListCapacity = 16; | 6313 static const int kMaxInitialListCapacity = 16; |
| 6118 | 6314 |
| 6119 Zone* zone = isolate->runtime_zone(); | 6315 Zone zone(isolate); |
| 6120 ZoneScope scope(zone, DELETE_ON_EXIT); | |
| 6121 | 6316 |
| 6122 // Find (up to limit) indices of separator and end-of-string in subject | 6317 // Find (up to limit) indices of separator and end-of-string in subject |
| 6123 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 6318 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
| 6124 ZoneList<int> indices(initial_capacity, zone); | 6319 ZoneList<int> indices(initial_capacity, &zone); |
| 6125 if (!pattern->IsFlat()) FlattenString(pattern); | 6320 if (!pattern->IsFlat()) FlattenString(pattern); |
| 6126 | 6321 |
| 6127 FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit, zone); | 6322 FindStringIndicesDispatch(isolate, *subject, *pattern, |
| 6323 &indices, limit, &zone); |
| 6128 | 6324 |
| 6129 if (static_cast<uint32_t>(indices.length()) < limit) { | 6325 if (static_cast<uint32_t>(indices.length()) < limit) { |
| 6130 indices.Add(subject_length, zone); | 6326 indices.Add(subject_length, &zone); |
| 6131 } | 6327 } |
| 6132 | 6328 |
| 6133 // The list indices now contains the end of each part to create. | 6329 // The list indices now contains the end of each part to create. |
| 6134 | 6330 |
| 6135 // Create JSArray of substrings separated by separator. | 6331 // Create JSArray of substrings separated by separator. |
| 6136 int part_count = indices.length(); | 6332 int part_count = indices.length(); |
| 6137 | 6333 |
| 6138 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6334 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
| 6139 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); | 6335 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); |
| 6140 if (maybe_result->IsFailure()) return maybe_result; | 6336 if (maybe_result->IsFailure()) return maybe_result; |
| (...skipping 1782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7923 Compiler::RecompileParallel(function); | 8119 Compiler::RecompileParallel(function); |
| 7924 return isolate->heap()->undefined_value(); | 8120 return isolate->heap()->undefined_value(); |
| 7925 } | 8121 } |
| 7926 | 8122 |
| 7927 | 8123 |
| 7928 RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) { | 8124 RUNTIME_FUNCTION(MaybeObject*, Runtime_InstallRecompiledCode) { |
| 7929 HandleScope handle_scope(isolate); | 8125 HandleScope handle_scope(isolate); |
| 7930 ASSERT(args.length() == 1); | 8126 ASSERT(args.length() == 1); |
| 7931 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8127 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 7932 ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation); | 8128 ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation); |
| 7933 OptimizingCompilerThread* opt_thread = isolate->optimizing_compiler_thread(); | 8129 isolate->optimizing_compiler_thread()->InstallOptimizedFunctions(); |
| 7934 do { | |
| 7935 // The function could have been marked for installing, but not queued just | |
| 7936 // yet. In this case, retry until installed. | |
| 7937 opt_thread->InstallOptimizedFunctions(); | |
| 7938 } while (function->IsMarkedForInstallingRecompiledCode()); | |
| 7939 return function->code(); | 8130 return function->code(); |
| 7940 } | 8131 } |
| 7941 | 8132 |
| 7942 | 8133 |
| 7943 class ActivationsFinder : public ThreadVisitor { | 8134 class ActivationsFinder : public ThreadVisitor { |
| 7944 public: | 8135 public: |
| 7945 explicit ActivationsFinder(JSFunction* function) | 8136 explicit ActivationsFinder(JSFunction* function) |
| 7946 : function_(function), has_activations_(false) {} | 8137 : function_(function), has_activations_(false) {} |
| 7947 | 8138 |
| 7948 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 8139 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
| (...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9117 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); | 9308 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |
| 9118 return JSGlobalObject::cast(global)->global_receiver(); | 9309 return JSGlobalObject::cast(global)->global_receiver(); |
| 9119 } | 9310 } |
| 9120 | 9311 |
| 9121 | 9312 |
| 9122 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { | 9313 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { |
| 9123 HandleScope scope(isolate); | 9314 HandleScope scope(isolate); |
| 9124 ASSERT_EQ(1, args.length()); | 9315 ASSERT_EQ(1, args.length()); |
| 9125 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9316 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
| 9126 | 9317 |
| 9127 Zone* zone = isolate->runtime_zone(); | |
| 9128 source = Handle<String>(source->TryFlattenGetString()); | 9318 source = Handle<String>(source->TryFlattenGetString()); |
| 9129 // Optimized fast case where we only have ASCII characters. | 9319 // Optimized fast case where we only have ASCII characters. |
| 9130 Handle<Object> result; | 9320 Handle<Object> result; |
| 9131 if (source->IsSeqOneByteString()) { | 9321 if (source->IsSeqOneByteString()) { |
| 9132 result = JsonParser<true>::Parse(source, zone); | 9322 result = JsonParser<true>::Parse(source); |
| 9133 } else { | 9323 } else { |
| 9134 result = JsonParser<false>::Parse(source, zone); | 9324 result = JsonParser<false>::Parse(source); |
| 9135 } | 9325 } |
| 9136 if (result.is_null()) { | 9326 if (result.is_null()) { |
| 9137 // Syntax error or stack overflow in scanner. | 9327 // Syntax error or stack overflow in scanner. |
| 9138 ASSERT(isolate->has_pending_exception()); | 9328 ASSERT(isolate->has_pending_exception()); |
| 9139 return Failure::Exception(); | 9329 return Failure::Exception(); |
| 9140 } | 9330 } |
| 9141 return *result; | 9331 return *result; |
| 9142 } | 9332 } |
| 9143 | 9333 |
| 9144 | 9334 |
| (...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11577 for (ScopeIterator it(isolate, frame, 0); | 11767 for (ScopeIterator it(isolate, frame, 0); |
| 11578 !it.Done(); | 11768 !it.Done(); |
| 11579 it.Next()) { | 11769 it.Next()) { |
| 11580 n++; | 11770 n++; |
| 11581 } | 11771 } |
| 11582 | 11772 |
| 11583 return Smi::FromInt(n); | 11773 return Smi::FromInt(n); |
| 11584 } | 11774 } |
| 11585 | 11775 |
| 11586 | 11776 |
| 11777 // Returns the list of step-in positions (text offset) in a function of the |
| 11778 // stack frame in a range from the current debug break position to the end |
| 11779 // of the corresponding statement. |
| 11780 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetStepInPositions) { |
| 11781 HandleScope scope(isolate); |
| 11782 ASSERT(args.length() == 2); |
| 11783 |
| 11784 // Check arguments. |
| 11785 Object* check; |
| 11786 { MaybeObject* maybe_check = Runtime_CheckExecutionState( |
| 11787 RUNTIME_ARGUMENTS(isolate, args)); |
| 11788 if (!maybe_check->ToObject(&check)) return maybe_check; |
| 11789 } |
| 11790 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
| 11791 |
| 11792 // Get the frame where the debugging is performed. |
| 11793 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
| 11794 JavaScriptFrameIterator frame_it(isolate, id); |
| 11795 JavaScriptFrame* frame = frame_it.frame(); |
| 11796 |
| 11797 Handle<SharedFunctionInfo> shared = |
| 11798 Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); |
| 11799 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); |
| 11800 |
| 11801 int len = 0; |
| 11802 Handle<JSArray> array(isolate->factory()->NewJSArray(10)); |
| 11803 // Find the break point where execution has stopped. |
| 11804 BreakLocationIterator break_location_iterator(debug_info, |
| 11805 ALL_BREAK_LOCATIONS); |
| 11806 |
| 11807 break_location_iterator.FindBreakLocationFromAddress(frame->pc()); |
| 11808 int current_statement_pos = break_location_iterator.statement_position(); |
| 11809 |
| 11810 while (!break_location_iterator.Done()) { |
| 11811 if (break_location_iterator.IsStepInLocation(isolate)) { |
| 11812 Smi* position_value = Smi::FromInt(break_location_iterator.position()); |
| 11813 JSObject::SetElement(array, len, |
| 11814 Handle<Object>(position_value, isolate), |
| 11815 NONE, kNonStrictMode); |
| 11816 len++; |
| 11817 } |
| 11818 // Advance iterator. |
| 11819 break_location_iterator.Next(); |
| 11820 if (current_statement_pos != |
| 11821 break_location_iterator.statement_position()) { |
| 11822 break; |
| 11823 } |
| 11824 } |
| 11825 return *array; |
| 11826 } |
| 11827 |
| 11828 |
| 11587 static const int kScopeDetailsTypeIndex = 0; | 11829 static const int kScopeDetailsTypeIndex = 0; |
| 11588 static const int kScopeDetailsObjectIndex = 1; | 11830 static const int kScopeDetailsObjectIndex = 1; |
| 11589 static const int kScopeDetailsSize = 2; | 11831 static const int kScopeDetailsSize = 2; |
| 11590 | 11832 |
| 11591 | 11833 |
| 11592 static MaybeObject* MaterializeScopeDetails(Isolate* isolate, | 11834 static MaybeObject* MaterializeScopeDetails(Isolate* isolate, |
| 11593 ScopeIterator* it) { | 11835 ScopeIterator* it) { |
| 11594 // Calculate the size of the result. | 11836 // Calculate the size of the result. |
| 11595 int details_size = kScopeDetailsSize; | 11837 int details_size = kScopeDetailsSize; |
| 11596 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | 11838 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12171 // Evaluate a piece of JavaScript in the context of a stack frame for | 12413 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 12172 // debugging. This is done by creating a new context which in its extension | 12414 // debugging. This is done by creating a new context which in its extension |
| 12173 // part has all the parameters and locals of the function on the stack frame | 12415 // part has all the parameters and locals of the function on the stack frame |
| 12174 // as well as a materialized arguments object. As this context replaces | 12416 // as well as a materialized arguments object. As this context replaces |
| 12175 // the context of the function on the stack frame a new (empty) function | 12417 // the context of the function on the stack frame a new (empty) function |
| 12176 // is created as well to be used as the closure for the context. | 12418 // is created as well to be used as the closure for the context. |
| 12177 // This closure as replacements for the one on the stack frame presenting | 12419 // This closure as replacements for the one on the stack frame presenting |
| 12178 // the same view of the values of parameters and local variables as if the | 12420 // the same view of the values of parameters and local variables as if the |
| 12179 // piece of JavaScript was evaluated at the point where the function on the | 12421 // piece of JavaScript was evaluated at the point where the function on the |
| 12180 // stack frame is currently stopped when we compile and run the (direct) eval. | 12422 // stack frame is currently stopped when we compile and run the (direct) eval. |
| 12423 // Returns array of |
| 12424 // #0: evaluate result |
| 12425 // #1: local variables materizalized again as object after evaluation, contain |
| 12426 // original variable values as they remained on stack |
| 12427 // #2: local variables materizalized as object before evaluation (and possibly |
| 12428 // modified by expression having been executed) |
| 12429 // Since user expression only reaches (and modifies) copies of local variables, |
| 12430 // those copies are returned to the caller to allow tracking the changes and |
| 12431 // manually updating the actual variables. |
| 12181 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { | 12432 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
| 12182 HandleScope scope(isolate); | 12433 HandleScope scope(isolate); |
| 12183 | 12434 |
| 12184 // Check the execution state and decode arguments frame and source to be | 12435 // Check the execution state and decode arguments frame and source to be |
| 12185 // evaluated. | 12436 // evaluated. |
| 12186 ASSERT(args.length() == 6); | 12437 ASSERT(args.length() == 6); |
| 12187 Object* check_result; | 12438 Object* check_result; |
| 12188 { MaybeObject* maybe_result = Runtime_CheckExecutionState( | 12439 { MaybeObject* maybe_result = Runtime_CheckExecutionState( |
| 12189 RUNTIME_ARGUMENTS(isolate, args)); | 12440 RUNTIME_ARGUMENTS(isolate, args)); |
| 12190 if (!maybe_result->ToObject(&check_result)) return maybe_result; | 12441 if (!maybe_result->ToObject(&check_result)) return maybe_result; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12270 frame, | 12521 frame, |
| 12271 inlined_jsframe_index); | 12522 inlined_jsframe_index); |
| 12272 if (context.is_null()) { | 12523 if (context.is_null()) { |
| 12273 ASSERT(isolate->has_pending_exception()); | 12524 ASSERT(isolate->has_pending_exception()); |
| 12274 MaybeObject* exception = isolate->pending_exception(); | 12525 MaybeObject* exception = isolate->pending_exception(); |
| 12275 isolate->clear_pending_exception(); | 12526 isolate->clear_pending_exception(); |
| 12276 return exception; | 12527 return exception; |
| 12277 } | 12528 } |
| 12278 | 12529 |
| 12279 Handle<Object> receiver(frame->receiver(), isolate); | 12530 Handle<Object> receiver(frame->receiver(), isolate); |
| 12280 return DebugEvaluate(isolate, context, context_extension, receiver, source); | 12531 Object* evaluate_result_object; |
| 12532 { MaybeObject* maybe_result = |
| 12533 DebugEvaluate(isolate, context, context_extension, receiver, source); |
| 12534 if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result; |
| 12535 } |
| 12536 Handle<Object> evaluate_result(evaluate_result_object, isolate); |
| 12537 |
| 12538 Handle<JSObject> local_scope_control_copy = |
| 12539 MaterializeLocalScopeWithFrameInspector(isolate, frame, |
| 12540 &frame_inspector); |
| 12541 |
| 12542 Handle<FixedArray> resultArray = isolate->factory()->NewFixedArray(3); |
| 12543 resultArray->set(0, *evaluate_result); |
| 12544 resultArray->set(1, *local_scope_control_copy); |
| 12545 resultArray->set(2, *local_scope); |
| 12546 |
| 12547 return *(isolate->factory()->NewJSArrayWithElements(resultArray)); |
| 12281 } | 12548 } |
| 12282 | 12549 |
| 12283 | 12550 |
| 12284 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { | 12551 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { |
| 12285 HandleScope scope(isolate); | 12552 HandleScope scope(isolate); |
| 12286 | 12553 |
| 12287 // Check the execution state and decode arguments frame and source to be | 12554 // Check the execution state and decode arguments frame and source to be |
| 12288 // evaluated. | 12555 // evaluated. |
| 12289 ASSERT(args.length() == 4); | 12556 ASSERT(args.length() == 4); |
| 12290 Object* check_result; | 12557 Object* check_result; |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12844 // checks that none of them have activations on stacks (of any thread). | 13111 // checks that none of them have activations on stacks (of any thread). |
| 12845 // Returns array of the same length with corresponding results of | 13112 // Returns array of the same length with corresponding results of |
| 12846 // LiveEdit::FunctionPatchabilityStatus type. | 13113 // LiveEdit::FunctionPatchabilityStatus type. |
| 12847 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) { | 13114 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCheckAndDropActivations) { |
| 12848 HandleScope scope(isolate); | 13115 HandleScope scope(isolate); |
| 12849 CHECK(isolate->debugger()->live_edit_enabled()); | 13116 CHECK(isolate->debugger()->live_edit_enabled()); |
| 12850 ASSERT(args.length() == 2); | 13117 ASSERT(args.length() == 2); |
| 12851 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0); | 13118 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0); |
| 12852 CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1); | 13119 CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1); |
| 12853 | 13120 |
| 12854 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop, | 13121 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); |
| 12855 isolate->runtime_zone()); | |
| 12856 } | 13122 } |
| 12857 | 13123 |
| 12858 // Compares 2 strings line-by-line, then token-wise and returns diff in form | 13124 // Compares 2 strings line-by-line, then token-wise and returns diff in form |
| 12859 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list | 13125 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list |
| 12860 // of diff chunks. | 13126 // of diff chunks. |
| 12861 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) { | 13127 RUNTIME_FUNCTION(MaybeObject*, Runtime_LiveEditCompareStrings) { |
| 12862 HandleScope scope(isolate); | 13128 HandleScope scope(isolate); |
| 12863 CHECK(isolate->debugger()->live_edit_enabled()); | 13129 CHECK(isolate->debugger()->live_edit_enabled()); |
| 12864 ASSERT(args.length() == 2); | 13130 ASSERT(args.length() == 2); |
| 12865 CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); | 13131 CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 12893 } | 13159 } |
| 12894 | 13160 |
| 12895 int count = 0; | 13161 int count = 0; |
| 12896 JavaScriptFrameIterator it(isolate, id); | 13162 JavaScriptFrameIterator it(isolate, id); |
| 12897 for (; !it.done(); it.Advance()) { | 13163 for (; !it.done(); it.Advance()) { |
| 12898 if (index < count + it.frame()->GetInlineCount()) break; | 13164 if (index < count + it.frame()->GetInlineCount()) break; |
| 12899 count += it.frame()->GetInlineCount(); | 13165 count += it.frame()->GetInlineCount(); |
| 12900 } | 13166 } |
| 12901 if (it.done()) return heap->undefined_value(); | 13167 if (it.done()) return heap->undefined_value(); |
| 12902 | 13168 |
| 12903 const char* error_message = | 13169 const char* error_message = LiveEdit::RestartFrame(it.frame()); |
| 12904 LiveEdit::RestartFrame(it.frame(), isolate->runtime_zone()); | |
| 12905 if (error_message) { | 13170 if (error_message) { |
| 12906 return *(isolate->factory()->InternalizeUtf8String(error_message)); | 13171 return *(isolate->factory()->InternalizeUtf8String(error_message)); |
| 12907 } | 13172 } |
| 12908 return heap->true_value(); | 13173 return heap->true_value(); |
| 12909 } | 13174 } |
| 12910 | 13175 |
| 12911 | 13176 |
| 12912 // A testing entry. Returns statement position which is the closest to | 13177 // A testing entry. Returns statement position which is the closest to |
| 12913 // source_position. | 13178 // source_position. |
| 12914 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) { | 13179 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionCodePositionFromSource) { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13104 | 13369 |
| 13105 | 13370 |
| 13106 // Retrieve the stack trace. This could be the raw stack trace collected | 13371 // Retrieve the stack trace. This could be the raw stack trace collected |
| 13107 // on stack overflow or the already formatted stack trace string. | 13372 // on stack overflow or the already formatted stack trace string. |
| 13108 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { | 13373 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOverflowedStackTrace) { |
| 13109 HandleScope scope(isolate); | 13374 HandleScope scope(isolate); |
| 13110 ASSERT_EQ(args.length(), 1); | 13375 ASSERT_EQ(args.length(), 1); |
| 13111 CONVERT_ARG_CHECKED(JSObject, error_object, 0); | 13376 CONVERT_ARG_CHECKED(JSObject, error_object, 0); |
| 13112 String* key = isolate->heap()->hidden_stack_trace_string(); | 13377 String* key = isolate->heap()->hidden_stack_trace_string(); |
| 13113 Object* result = error_object->GetHiddenProperty(key); | 13378 Object* result = error_object->GetHiddenProperty(key); |
| 13379 if (result->IsTheHole()) result = isolate->heap()->undefined_value(); |
| 13114 RUNTIME_ASSERT(result->IsJSArray() || | 13380 RUNTIME_ASSERT(result->IsJSArray() || |
| 13115 result->IsString() || | 13381 result->IsString() || |
| 13116 result->IsUndefined()); | 13382 result->IsUndefined()); |
| 13117 return result; | 13383 return result; |
| 13118 } | 13384 } |
| 13119 | 13385 |
| 13120 | 13386 |
| 13121 // Set or clear the stack trace attached to an stack overflow error object. | 13387 // Set or clear the stack trace attached to an stack overflow error object. |
| 13122 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { | 13388 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetOverflowedStackTrace) { |
| 13123 HandleScope scope(isolate); | 13389 HandleScope scope(isolate); |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13653 // Handle last resort GC and make sure to allow future allocations | 13919 // Handle last resort GC and make sure to allow future allocations |
| 13654 // to grow the heap without causing GCs (if possible). | 13920 // to grow the heap without causing GCs (if possible). |
| 13655 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13921 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13656 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13922 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13657 "Runtime::PerformGC"); | 13923 "Runtime::PerformGC"); |
| 13658 } | 13924 } |
| 13659 } | 13925 } |
| 13660 | 13926 |
| 13661 | 13927 |
| 13662 } } // namespace v8::internal | 13928 } } // namespace v8::internal |
| OLD | NEW |