Chromium Code Reviews| 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 |