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

Side by Side Diff: src/runtime.cc

Issue 17153011: DataView implementation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Self-review Created 7 years, 6 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
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698