| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdio.h> | 5 #include <stdio.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 #include <limits> |
| 7 | 8 |
| 8 #include "dart/runtime/include/dart_api.h" | 9 #include "dart/runtime/include/dart_api.h" |
| 9 #include "mojo/dart/embedder/builtin.h" | 10 #include "mojo/dart/embedder/builtin.h" |
| 10 #include "mojo/dart/embedder/common.h" | 11 #include "mojo/dart/embedder/common.h" |
| 12 #include "mojo/dart/embedder/io/filter.h" |
| 11 #include "mojo/dart/embedder/io/internet_address.h" | 13 #include "mojo/dart/embedder/io/internet_address.h" |
| 12 #include "mojo/dart/embedder/mojo_dart_state.h" | 14 #include "mojo/dart/embedder/mojo_dart_state.h" |
| 13 #include "mojo/public/cpp/system/macros.h" | 15 #include "mojo/public/cpp/system/macros.h" |
| 14 | 16 |
| 15 namespace mojo { | 17 namespace mojo { |
| 16 namespace dart { | 18 namespace dart { |
| 17 | 19 |
| 18 #define MOJO_IO_NATIVE_LIST(V) \ | 20 #define MOJO_IO_NATIVE_LIST(V) \ |
| 21 V(Filter_CreateZLibDeflate, 8) \ |
| 22 V(Filter_CreateZLibInflate, 4) \ |
| 23 V(Filter_End, 1) \ |
| 24 V(Filter_Process, 4) \ |
| 25 V(Filter_Processed, 3) \ |
| 19 V(InternetAddress_Parse, 1) \ | 26 V(InternetAddress_Parse, 1) \ |
| 20 V(InternetAddress_Reverse, 1) \ | 27 V(InternetAddress_Reverse, 1) \ |
| 21 V(Platform_NumberOfProcessors, 0) \ | 28 V(Platform_NumberOfProcessors, 0) \ |
| 22 V(Platform_OperatingSystem, 0) \ | 29 V(Platform_OperatingSystem, 0) \ |
| 23 V(Platform_PathSeparator, 0) \ | 30 V(Platform_PathSeparator, 0) \ |
| 24 V(Platform_LocalHostname, 0) \ | 31 V(Platform_LocalHostname, 0) \ |
| 25 V(Platform_ExecutableName, 0) \ | 32 V(Platform_ExecutableName, 0) \ |
| 26 V(Platform_Environment, 0) \ | 33 V(Platform_Environment, 0) \ |
| 27 V(Platform_ExecutableArguments, 0) \ | 34 V(Platform_ExecutableArguments, 0) \ |
| 28 V(Platform_PackageRoot, 0) \ | 35 V(Platform_PackageRoot, 0) \ |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries); | 68 size_t num_entries = MOJO_ARRAYSIZE(MojoEntries); |
| 62 for (size_t i = 0; i < num_entries; ++i) { | 69 for (size_t i = 0; i < num_entries; ++i) { |
| 63 const struct NativeEntries& entry = MojoEntries[i]; | 70 const struct NativeEntries& entry = MojoEntries[i]; |
| 64 if (entry.function == nf) { | 71 if (entry.function == nf) { |
| 65 return reinterpret_cast<const uint8_t*>(entry.name); | 72 return reinterpret_cast<const uint8_t*>(entry.name); |
| 66 } | 73 } |
| 67 } | 74 } |
| 68 return nullptr; | 75 return nullptr; |
| 69 } | 76 } |
| 70 | 77 |
| 78 class IOBuffer { |
| 79 public: |
| 80 static Dart_Handle Allocate(intptr_t size, uint8_t **buffer) { |
| 81 uint8_t* data = Allocate(size); |
| 82 Dart_Handle result = Dart_NewExternalTypedData( |
| 83 Dart_TypedData_kUint8, data, size); |
| 84 Dart_NewWeakPersistentHandle(result, data, size, IOBuffer::Finalizer); |
| 85 |
| 86 if (Dart_IsError(result)) { |
| 87 Free(data); |
| 88 Dart_PropagateError(result); |
| 89 } |
| 90 if (buffer != NULL) { |
| 91 *buffer = data; |
| 92 } |
| 93 return result; |
| 94 } |
| 95 |
| 96 // Allocate IO buffer storage. |
| 97 static uint8_t* Allocate(intptr_t size) { |
| 98 return new uint8_t[size]; |
| 99 } |
| 100 |
| 101 // Function for disposing of IO buffer storage. All backing storage |
| 102 // for IO buffers must be freed using this function. |
| 103 static void Free(void* buffer) { |
| 104 delete[] reinterpret_cast<uint8_t*>(buffer); |
| 105 } |
| 106 |
| 107 // Function for finalizing external byte arrays used as IO buffers. |
| 108 static void Finalizer(void* isolate_callback_data, |
| 109 Dart_WeakPersistentHandle handle, |
| 110 void* buffer) { |
| 111 Free(buffer); |
| 112 } |
| 113 |
| 114 private: |
| 115 DISALLOW_IMPLICIT_CONSTRUCTORS(IOBuffer); |
| 116 }; |
| 117 |
| 118 static Filter* GetFilter(Dart_Handle filter_obj) { |
| 119 Filter* filter; |
| 120 Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter); |
| 121 if (Dart_IsError(result)) { |
| 122 Dart_PropagateError(result); |
| 123 } |
| 124 if (filter == NULL) { |
| 125 Dart_ThrowException(DartEmbedder::NewInternalError("Filter destroyed")); |
| 126 } |
| 127 return filter; |
| 128 } |
| 129 |
| 130 static void EndFilter(Dart_Handle filter_obj, Filter* filter) { |
| 131 Filter::SetFilterPointerNativeField(filter_obj, NULL); |
| 132 delete filter; |
| 133 } |
| 134 |
| 135 static uint8_t* copyDictionary(Dart_Handle dictionary_obj) { |
| 136 uint8_t* src = NULL; |
| 137 intptr_t size; |
| 138 Dart_TypedData_Type type; |
| 139 |
| 140 if (Dart_IsError(Dart_ListLength(dictionary_obj, &size))) { |
| 141 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 142 "Failed to get the zlib dictionary length")); |
| 143 } |
| 144 |
| 145 uint8_t* dictionary = new uint8_t[size]; |
| 146 |
| 147 if (dictionary == NULL) { |
| 148 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 149 "Failed to allocate buffer for the zlib dictionary")); |
| 150 } |
| 151 |
| 152 Dart_Handle result = Dart_TypedDataAcquireData( |
| 153 dictionary_obj, &type, reinterpret_cast<void**>(&src), &size); |
| 154 if (!Dart_IsError(result)) { |
| 155 memmove(dictionary, src, size); |
| 156 Dart_TypedDataReleaseData(dictionary_obj); |
| 157 } else { |
| 158 if (Dart_IsError(Dart_ListGetAsBytes(dictionary_obj, 0, dictionary, |
| 159 size))) { |
| 160 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 161 "Failed to get the zlib dictionary")); |
| 162 } |
| 163 } |
| 164 |
| 165 return dictionary; |
| 166 } |
| 167 |
| 168 void Filter_CreateZLibInflate(Dart_NativeArguments args) { |
| 169 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 170 Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 1); |
| 171 int64_t window_bits = DartEmbedder::GetIntegerValue(window_bits_obj); |
| 172 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 2); |
| 173 uint8_t* dictionary = NULL; |
| 174 intptr_t dictionary_length = 0; |
| 175 if (!Dart_IsNull(dict_obj)) { |
| 176 dictionary = copyDictionary(dict_obj); |
| 177 if (dictionary != NULL) { |
| 178 dictionary_length = 0; |
| 179 Dart_ListLength(dict_obj, &dictionary_length); |
| 180 } |
| 181 } |
| 182 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3); |
| 183 bool raw; |
| 184 if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) { |
| 185 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 186 "Failed to get 'raw' parameter")); |
| 187 } |
| 188 Filter* filter = new ZLibInflateFilter(static_cast<int32_t>(window_bits), |
| 189 dictionary, dictionary_length, raw); |
| 190 if (!filter->Init()) { |
| 191 delete filter; |
| 192 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 193 "Failed to create ZLibInflateFilter")); |
| 194 } |
| 195 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); |
| 196 if (Dart_IsError(result)) { |
| 197 delete filter; |
| 198 Dart_PropagateError(result); |
| 199 } |
| 200 } |
| 201 |
| 202 void Filter_CreateZLibDeflate(Dart_NativeArguments args) { |
| 203 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 204 Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1); |
| 205 bool gzip = DartEmbedder::GetBooleanValue(gzip_obj); |
| 206 Dart_Handle level_obj = Dart_GetNativeArgument(args, 2); |
| 207 int64_t level = DartEmbedder::GetInt64ValueCheckRange( |
| 208 level_obj, |
| 209 std::numeric_limits<int32_t>::min(), |
| 210 std::numeric_limits<int32_t>::max()); |
| 211 Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 3); |
| 212 int64_t window_bits = DartEmbedder::GetIntegerValue(window_bits_obj); |
| 213 Dart_Handle mLevel_obj = Dart_GetNativeArgument(args, 4); |
| 214 int64_t mem_level = DartEmbedder::GetIntegerValue(mLevel_obj); |
| 215 Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5); |
| 216 int64_t strategy = DartEmbedder::GetIntegerValue(strategy_obj); |
| 217 Dart_Handle dict_obj = Dart_GetNativeArgument(args, 6); |
| 218 uint8_t* dictionary = NULL; |
| 219 intptr_t dictionary_length = 0; |
| 220 if (!Dart_IsNull(dict_obj)) { |
| 221 dictionary = copyDictionary(dict_obj); |
| 222 if (dictionary != NULL) { |
| 223 dictionary_length = 0; |
| 224 Dart_ListLength(dict_obj, &dictionary_length); |
| 225 } |
| 226 } |
| 227 Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7); |
| 228 bool raw = DartEmbedder::GetBooleanValue(raw_obj); |
| 229 Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level), |
| 230 static_cast<int32_t>(window_bits), |
| 231 static_cast<int32_t>(mem_level), |
| 232 static_cast<int32_t>(strategy), |
| 233 dictionary, dictionary_length, raw); |
| 234 if (!filter->Init()) { |
| 235 delete filter; |
| 236 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 237 "Failed to create ZLibDeflateFilter")); |
| 238 } |
| 239 Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter); |
| 240 if (Dart_IsError(result)) { |
| 241 delete filter; |
| 242 Dart_PropagateError(result); |
| 243 } |
| 244 } |
| 245 |
| 246 void Filter_Process(Dart_NativeArguments args) { |
| 247 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 248 Filter* filter = GetFilter(filter_obj); |
| 249 Dart_Handle data_obj = Dart_GetNativeArgument(args, 1); |
| 250 intptr_t start = |
| 251 DartEmbedder::GetIntptrValue(Dart_GetNativeArgument(args, 2)); |
| 252 intptr_t end = DartEmbedder::GetIntptrValue(Dart_GetNativeArgument(args, 3)); |
| 253 intptr_t chunk_length = end - start; |
| 254 intptr_t length; |
| 255 Dart_TypedData_Type type; |
| 256 uint8_t* buffer = NULL; |
| 257 Dart_Handle result = Dart_TypedDataAcquireData( |
| 258 data_obj, &type, reinterpret_cast<void**>(&buffer), &length); |
| 259 |
| 260 if (!Dart_IsError(result)) { |
| 261 DCHECK(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8); |
| 262 if (type != Dart_TypedData_kUint8 && type != Dart_TypedData_kInt8) { |
| 263 Dart_TypedDataReleaseData(data_obj); |
| 264 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 265 "Invalid argument passed to Filter_Process")); |
| 266 } |
| 267 uint8_t* zlib_buffer = new uint8_t[chunk_length]; |
| 268 if (zlib_buffer == NULL) { |
| 269 Dart_TypedDataReleaseData(data_obj); |
| 270 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 271 "Failed to allocate buffer for zlib")); |
| 272 } |
| 273 memmove(zlib_buffer, buffer + start, chunk_length); |
| 274 Dart_TypedDataReleaseData(data_obj); |
| 275 buffer = zlib_buffer; |
| 276 } else { |
| 277 if (Dart_IsError(Dart_ListLength(data_obj, &length))) { |
| 278 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 279 "Failed to get list length")); |
| 280 } |
| 281 buffer = new uint8_t[chunk_length]; |
| 282 if (Dart_IsError(Dart_ListGetAsBytes( |
| 283 data_obj, start, buffer, chunk_length))) { |
| 284 delete[] buffer; |
| 285 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 286 "Failed to get list bytes")); |
| 287 } |
| 288 } |
| 289 // Process will take ownership of buffer, if successful. |
| 290 if (!filter->Process(buffer, chunk_length)) { |
| 291 delete[] buffer; |
| 292 EndFilter(filter_obj, filter); |
| 293 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 294 "Call to Process while still processing data")); |
| 295 } |
| 296 } |
| 297 |
| 298 void Filter_Processed(Dart_NativeArguments args) { |
| 299 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 300 Filter* filter = GetFilter(filter_obj); |
| 301 Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1); |
| 302 bool flush; |
| 303 if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) { |
| 304 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 305 "Failed to get 'flush' parameter")); |
| 306 } |
| 307 Dart_Handle end_obj = Dart_GetNativeArgument(args, 2); |
| 308 bool end; |
| 309 if (Dart_IsError(Dart_BooleanValue(end_obj, &end))) { |
| 310 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 311 "Failed to get 'end' parameter")); |
| 312 } |
| 313 intptr_t read = filter->Processed(filter->processed_buffer(), |
| 314 filter->processed_buffer_size(), |
| 315 flush, |
| 316 end); |
| 317 if (read < 0) { |
| 318 // Error, end filter. |
| 319 EndFilter(filter_obj, filter); |
| 320 Dart_ThrowException(DartEmbedder::NewInternalError( |
| 321 "Filter error, bad data")); |
| 322 } else if (read == 0) { |
| 323 Dart_SetReturnValue(args, Dart_Null()); |
| 324 } else { |
| 325 uint8_t* io_buffer; |
| 326 Dart_Handle result = IOBuffer::Allocate(read, &io_buffer); |
| 327 memmove(io_buffer, filter->processed_buffer(), read); |
| 328 Dart_SetReturnValue(args, result); |
| 329 } |
| 330 } |
| 331 |
| 332 void Filter_End(Dart_NativeArguments args) { |
| 333 Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0); |
| 334 Filter* filter = GetFilter(filter_obj); |
| 335 EndFilter(filter_obj, filter); |
| 336 } |
| 337 |
| 71 void InternetAddress_Parse(Dart_NativeArguments arguments) { | 338 void InternetAddress_Parse(Dart_NativeArguments arguments) { |
| 72 const char* address = DartEmbedder::GetStringArgument(arguments, 0); | 339 const char* address = DartEmbedder::GetStringArgument(arguments, 0); |
| 73 CHECK(address != nullptr); | 340 CHECK(address != nullptr); |
| 74 RawAddr raw; | 341 RawAddr raw; |
| 75 int type = strchr(address, ':') == nullptr ? InternetAddress::TYPE_IPV4 | 342 int type = strchr(address, ':') == nullptr ? InternetAddress::TYPE_IPV4 |
| 76 : InternetAddress::TYPE_IPV6; | 343 : InternetAddress::TYPE_IPV6; |
| 77 intptr_t length = (type == InternetAddress::TYPE_IPV4) ? | 344 intptr_t length = (type == InternetAddress::TYPE_IPV4) ? |
| 78 IPV4_RAW_ADDR_LENGTH : IPV6_RAW_ADDR_LENGTH; | 345 IPV4_RAW_ADDR_LENGTH : IPV6_RAW_ADDR_LENGTH; |
| 79 if (InternetAddress::Parse(type, address, &raw)) { | 346 if (InternetAddress::Parse(type, address, &raw)) { |
| 80 Dart_SetReturnValue(arguments, | 347 Dart_SetReturnValue(arguments, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 void Process_Pid(Dart_NativeArguments arguments) { | 440 void Process_Pid(Dart_NativeArguments arguments) { |
| 174 // TODO(rudominer) After sandboxing is implemented getpid() will not return | 441 // TODO(rudominer) After sandboxing is implemented getpid() will not return |
| 175 // the real pid. Most likely it will return the value 1. We need to decide | 442 // the real pid. Most likely it will return the value 1. We need to decide |
| 176 // what behavior we want Dart's pid getter to have when sandboxed. | 443 // what behavior we want Dart's pid getter to have when sandboxed. |
| 177 pid_t pid = getpid(); | 444 pid_t pid = getpid(); |
| 178 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(pid)); | 445 Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(pid)); |
| 179 } | 446 } |
| 180 | 447 |
| 181 } // namespace dart | 448 } // namespace dart |
| 182 } // namespace mojo | 449 } // namespace mojo |
| OLD | NEW |