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 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
996 JSObject::SetElement( | 996 JSObject::SetElement( |
997 target, static_cast<uint32_t>(offset + idx), value, | 997 target, static_cast<uint32_t>(offset + idx), value, |
998 NONE, kNonStrictMode); | 998 NONE, kNonStrictMode); |
999 } | 999 } |
1000 } | 1000 } |
1001 | 1001 |
1002 return isolate->heap()->true_value(); | 1002 return isolate->heap()->true_value(); |
1003 } | 1003 } |
1004 | 1004 |
1005 | 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_array()); | |
1025 buffer->set_weak_first_array(*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(Object, holder, 0); | |
1035 if (!holder->IsJSDataView()) { | |
rossberg
2013/06/21 08:44:01
Why not move this check to the JavaScript side? (h
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
| |
1036 return isolate->Throw(*isolate->factory()->NewTypeError( | |
1037 "not_data_view", HandleVector<Object>(NULL, 0))); | |
1038 } | |
1039 Handle<JSDataView> data_view(JSDataView::cast(*holder)); | |
1040 return data_view->buffer(); | |
1041 } | |
1042 | |
1043 | |
1044 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) { | |
1045 HandleScope scope(isolate); | |
1046 ASSERT(args.length() == 1); | |
1047 CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); | |
1048 if (!holder->IsJSDataView()) { | |
1049 return isolate->Throw(*isolate->factory()->NewTypeError( | |
1050 "not_data_view", HandleVector<Object>(NULL, 0))); | |
1051 } | |
1052 Handle<JSDataView> data_view(JSDataView::cast(*holder)); | |
1053 return data_view->byte_offset(); | |
1054 } | |
1055 | |
1056 | |
1057 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) { | |
1058 HandleScope scope(isolate); | |
1059 ASSERT(args.length() == 1); | |
1060 CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); | |
1061 if (!holder->IsJSDataView()) { | |
1062 return isolate->Throw(*isolate->factory()->NewTypeError( | |
1063 "not_data_view", HandleVector<Object>(NULL, 0))); | |
1064 } | |
1065 Handle<JSDataView> data_view(JSDataView::cast(*holder)); | |
1066 return data_view->byte_length(); | |
1067 } | |
1068 | |
1069 | |
1070 inline static bool NeedToFlipBytes(bool is_little_endian) { | |
1071 #ifdef V8_TARGET_LITTLE_ENDIAN | |
1072 return !is_little_endian; | |
1073 #else | |
1074 return is_little_endian; | |
1075 #endif | |
1076 } | |
1077 | |
1078 | |
1079 inline void SwapBytes(uint8_t* p, uint8_t* q) { | |
1080 uint8_t temp = *p; | |
rossberg
2013/06/21 08:44:01
Nit: indentation
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
| |
1081 *p = *q; | |
1082 *q = temp; | |
1083 } | |
1084 | |
1085 | |
1086 template<int n> | |
1087 void FlipBytes(uint8_t* p, bool is_little_endian); | |
1088 | |
1089 | |
1090 template<> | |
1091 void FlipBytes<1>(uint8_t*, bool) {} | |
1092 | |
1093 | |
1094 template<> | |
1095 void FlipBytes<2>(uint8_t* p, bool is_little_endian) { | |
1096 if (!NeedToFlipBytes(is_little_endian)) return; | |
1097 SwapBytes(p, p+1); | |
1098 } | |
1099 | |
1100 | |
1101 template<> | |
1102 void FlipBytes<4>(uint8_t* p, bool is_little_endian) { | |
1103 if (!NeedToFlipBytes(is_little_endian)) return; | |
1104 SwapBytes(p+1, p+2); | |
1105 SwapBytes(p, p+3); | |
1106 } | |
1107 | |
1108 | |
1109 template<> | |
1110 void FlipBytes<8>(uint8_t* p, bool is_little_endian) { | |
1111 if (!NeedToFlipBytes(is_little_endian)) return; | |
1112 SwapBytes(p+3, p+4); | |
1113 SwapBytes(p+2, p+5); | |
1114 SwapBytes(p+1, p+6); | |
1115 SwapBytes(p, p+7); | |
1116 } | |
1117 | |
1118 | |
1119 template<typename T> | |
1120 inline static bool DataViewGetValue( | |
1121 Isolate* isolate, | |
1122 Handle<JSDataView> data_view, | |
1123 Handle<Object> byte_offset_obj, | |
1124 bool is_little_endian, | |
1125 T* result) { | |
1126 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); | |
1127 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); | |
1128 | |
1129 size_t data_view_byte_offset = | |
1130 NumberToSize(isolate, data_view->byte_offset()); | |
1131 size_t data_view_byte_length = | |
1132 NumberToSize(isolate, data_view->byte_length()); | |
1133 if (byte_offset + sizeof(T) > data_view_byte_length || | |
1134 byte_offset + sizeof(T) < byte_offset) { // overflow | |
1135 return false; | |
1136 } | |
1137 | |
1138 union Value { | |
1139 T data; | |
rossberg
2013/06/21 08:44:01
Nit: indentation
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done. Didn't move this to v8utils.h, because it lo
| |
1140 uint8_t bytes[sizeof(T)]; | |
1141 }; | |
1142 | |
1143 Value value; | |
1144 size_t buffer_offset = data_view_byte_offset + byte_offset; | |
1145 ASSERT( | |
1146 NumberToSize(isolate, buffer->byte_length()) | |
1147 >= buffer_offset + sizeof(T)); | |
1148 OS::MemCopy(value.bytes, | |
rossberg
2013/06/21 08:44:01
OS::MemCopy seems overkill here. Use at least the
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
| |
1149 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset, | |
1150 sizeof(T)); | |
1151 FlipBytes<sizeof(T)>(value.bytes, is_little_endian); | |
1152 *result = value.data; | |
1153 return true; | |
1154 } | |
1155 | |
1156 | |
1157 template<typename T> | |
1158 static bool DataViewSetValue( | |
1159 Isolate* isolate, | |
1160 Handle<JSDataView> data_view, | |
1161 Handle<Object> byte_offset_obj, | |
1162 bool is_little_endian, | |
1163 T data) { | |
1164 size_t byte_offset = NumberToSize(isolate, *byte_offset_obj); | |
1165 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); | |
1166 | |
1167 size_t data_view_byte_offset = | |
1168 NumberToSize(isolate, data_view->byte_offset()); | |
1169 size_t data_view_byte_length = | |
1170 NumberToSize(isolate, data_view->byte_length()); | |
1171 if (byte_offset + sizeof(T) > data_view_byte_length || | |
1172 byte_offset + sizeof(T) < byte_offset) { // overflow | |
1173 return false; | |
1174 } | |
1175 | |
1176 union Value { | |
1177 T data; | |
rossberg
2013/06/21 08:44:01
Nit: indentation
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
| |
1178 uint8_t bytes[sizeof(T)]; | |
1179 }; | |
1180 | |
1181 Value value; | |
1182 value.data = data; | |
1183 size_t buffer_offset = data_view_byte_offset + byte_offset; | |
1184 ASSERT( | |
1185 NumberToSize(isolate, buffer->byte_length()) | |
1186 >= buffer_offset + sizeof(T)); | |
1187 FlipBytes<sizeof(T)>(value.bytes, is_little_endian); | |
1188 OS::MemCopy( | |
1189 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset, | |
1190 value.bytes, | |
1191 sizeof(T)); | |
1192 return true; | |
1193 } | |
1194 | |
1195 | |
1196 #define DATA_VIEW_GETTER(TypeName, Type, Convertor) \ | |
rossberg
2013/06/21 08:44:01
Nit: I think the spelling is Converter
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
Dmitry Lomov (no reviews)
2013/06/21 11:32:10
Done.
| |
1197 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGet##TypeName) { \ | |
1198 HandleScope scope(isolate); \ | |
1199 ASSERT(args.length() == 3); \ | |
1200 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ | |
1201 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ | |
1202 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2); \ | |
1203 Type result; \ | |
1204 if (DataViewGetValue( \ | |
1205 isolate, holder, offset, is_little_endian, &result)) { \ | |
1206 return isolate->heap()->Convertor(result); \ | |
1207 } else { \ | |
1208 return isolate->Throw(*isolate->factory()->NewRangeError( \ | |
1209 "invalid_data_view_accessor_offset", \ | |
1210 HandleVector<Object>(NULL, 0))); \ | |
1211 } \ | |
1212 } | |
1213 | |
1214 DATA_VIEW_GETTER(Uint8, uint8_t, NumberFromUint32) | |
1215 DATA_VIEW_GETTER(Int8, int8_t, NumberFromInt32) | |
1216 DATA_VIEW_GETTER(Uint16, uint16_t, NumberFromUint32) | |
1217 DATA_VIEW_GETTER(Int16, int16_t, NumberFromInt32) | |
1218 DATA_VIEW_GETTER(Uint32, uint32_t, NumberFromUint32) | |
1219 DATA_VIEW_GETTER(Int32, int32_t, NumberFromInt32) | |
1220 DATA_VIEW_GETTER(Float32, float, NumberFromDouble) | |
1221 DATA_VIEW_GETTER(Float64, double, NumberFromDouble) | |
1222 | |
1223 #undef DATA_VIEW_GETTER | |
1224 | |
1225 #define DATA_VIEW_SETTER(TypeName, Type) \ | |
1226 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewSet##TypeName) { \ | |
1227 HandleScope scope(isolate); \ | |
1228 ASSERT(args.length() == 4); \ | |
1229 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); \ | |
1230 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); \ | |
1231 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); \ | |
1232 CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3); \ | |
1233 Type v = static_cast<Type>(value->Number()); \ | |
1234 if (DataViewSetValue( \ | |
1235 isolate, holder, offset, is_little_endian, v)) { \ | |
1236 return isolate->heap()->undefined_value(); \ | |
1237 } else { \ | |
1238 return isolate->Throw(*isolate->factory()->NewRangeError( \ | |
1239 "invalid_data_view_accessor_offset", \ | |
1240 HandleVector<Object>(NULL, 0))); \ | |
1241 } \ | |
1242 } | |
1243 | |
1244 DATA_VIEW_SETTER(Uint8, uint8_t) | |
1245 DATA_VIEW_SETTER(Int8, int8_t) | |
1246 DATA_VIEW_SETTER(Uint16, uint16_t) | |
1247 DATA_VIEW_SETTER(Int16, int16_t) | |
1248 DATA_VIEW_SETTER(Uint32, uint32_t) | |
1249 DATA_VIEW_SETTER(Int32, int32_t) | |
1250 DATA_VIEW_SETTER(Float32, float) | |
1251 DATA_VIEW_SETTER(Float64, double) | |
1252 | |
1253 #undef DATA_VIEW_SETTER | |
1254 | |
1255 | |
1006 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { | 1256 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { |
1007 HandleScope scope(isolate); | 1257 HandleScope scope(isolate); |
1008 ASSERT(args.length() == 1); | 1258 ASSERT(args.length() == 1); |
1009 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); | 1259 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); |
1010 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); | 1260 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); |
1011 holder->set_table(*table); | 1261 holder->set_table(*table); |
1012 return *holder; | 1262 return *holder; |
1013 } | 1263 } |
1014 | 1264 |
1015 | 1265 |
(...skipping 12619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13635 // Handle last resort GC and make sure to allow future allocations | 13885 // Handle last resort GC and make sure to allow future allocations |
13636 // to grow the heap without causing GCs (if possible). | 13886 // to grow the heap without causing GCs (if possible). |
13637 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13887 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13638 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13888 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13639 "Runtime::PerformGC"); | 13889 "Runtime::PerformGC"); |
13640 } | 13890 } |
13641 } | 13891 } |
13642 | 13892 |
13643 | 13893 |
13644 } } // namespace v8::internal | 13894 } } // namespace v8::internal |
OLD | NEW |