| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 | |
| 6 #include "bin/loader.h" | 5 #include "bin/loader.h" |
| 7 | 6 |
| 8 #include "bin/builtin.h" | 7 #include "bin/builtin.h" |
| 9 #include "bin/dartutils.h" | 8 #include "bin/dartutils.h" |
| 10 #include "bin/dfe.h" | 9 #include "bin/dfe.h" |
| 11 #include "bin/extensions.h" | 10 #include "bin/extensions.h" |
| 12 #include "bin/file.h" | 11 #include "bin/file.h" |
| 13 #include "bin/lockers.h" | 12 #include "bin/lockers.h" |
| 14 #include "bin/utils.h" | 13 #include "bin/utils.h" |
| 15 #include "include/dart_tools_api.h" | 14 #include "include/dart_tools_api.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 39 results_capacity_(0), | 38 results_capacity_(0), |
| 40 payload_(NULL), | 39 payload_(NULL), |
| 41 payload_length_(0) { | 40 payload_length_(0) { |
| 42 monitor_ = new Monitor(); | 41 monitor_ = new Monitor(); |
| 43 ASSERT(isolate_data_ != NULL); | 42 ASSERT(isolate_data_ != NULL); |
| 44 port_ = Dart_NewNativePort("Loader", Loader::NativeMessageHandler, false); | 43 port_ = Dart_NewNativePort("Loader", Loader::NativeMessageHandler, false); |
| 45 isolate_data_->set_loader(this); | 44 isolate_data_->set_loader(this); |
| 46 AddLoader(port_, isolate_data_); | 45 AddLoader(port_, isolate_data_); |
| 47 } | 46 } |
| 48 | 47 |
| 49 | |
| 50 Loader::~Loader() { | 48 Loader::~Loader() { |
| 51 ASSERT(port_ != ILLEGAL_PORT); | 49 ASSERT(port_ != ILLEGAL_PORT); |
| 52 // Enter the monitor while we close the Dart port. After the Dart port is | 50 // Enter the monitor while we close the Dart port. After the Dart port is |
| 53 // closed, no more results can be queued. | 51 // closed, no more results can be queued. |
| 54 monitor_->Enter(); | 52 monitor_->Enter(); |
| 55 Dart_CloseNativePort(port_); | 53 Dart_CloseNativePort(port_); |
| 56 monitor_->Exit(); | 54 monitor_->Exit(); |
| 57 RemoveLoader(port_); | 55 RemoveLoader(port_); |
| 58 port_ = ILLEGAL_PORT; | 56 port_ = ILLEGAL_PORT; |
| 59 isolate_data_->set_loader(NULL); | 57 isolate_data_->set_loader(NULL); |
| 60 isolate_data_ = NULL; | 58 isolate_data_ = NULL; |
| 61 delete monitor_; | 59 delete monitor_; |
| 62 monitor_ = NULL; | 60 monitor_ = NULL; |
| 63 for (intptr_t i = 0; i < results_length_; i++) { | 61 for (intptr_t i = 0; i < results_length_; i++) { |
| 64 results_[i].Cleanup(); | 62 results_[i].Cleanup(); |
| 65 } | 63 } |
| 66 free(results_); | 64 free(results_); |
| 67 results_ = NULL; | 65 results_ = NULL; |
| 68 payload_ = NULL; | 66 payload_ = NULL; |
| 69 payload_length_ = 0; | 67 payload_length_ = 0; |
| 70 } | 68 } |
| 71 | 69 |
| 72 | |
| 73 // Copy the contents of |message| into an |IOResult|. | 70 // Copy the contents of |message| into an |IOResult|. |
| 74 void Loader::IOResult::Setup(Dart_CObject* message) { | 71 void Loader::IOResult::Setup(Dart_CObject* message) { |
| 75 ASSERT(message->type == Dart_CObject_kArray); | 72 ASSERT(message->type == Dart_CObject_kArray); |
| 76 ASSERT(message->value.as_array.length == 5); | 73 ASSERT(message->value.as_array.length == 5); |
| 77 Dart_CObject* tag_message = message->value.as_array.values[0]; | 74 Dart_CObject* tag_message = message->value.as_array.values[0]; |
| 78 ASSERT(tag_message != NULL); | 75 ASSERT(tag_message != NULL); |
| 79 Dart_CObject* uri_message = message->value.as_array.values[1]; | 76 Dart_CObject* uri_message = message->value.as_array.values[1]; |
| 80 ASSERT(uri_message != NULL); | 77 ASSERT(uri_message != NULL); |
| 81 Dart_CObject* resolved_uri_message = message->value.as_array.values[2]; | 78 Dart_CObject* resolved_uri_message = message->value.as_array.values[2]; |
| 82 ASSERT(resolved_uri_message != NULL); | 79 ASSERT(resolved_uri_message != NULL); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 // Payload is the contents of a file. | 112 // Payload is the contents of a file. |
| 116 ASSERT(payload_message->type == Dart_CObject_kTypedData); | 113 ASSERT(payload_message->type == Dart_CObject_kTypedData); |
| 117 ASSERT(payload_message->value.as_typed_data.type == Dart_TypedData_kUint8); | 114 ASSERT(payload_message->value.as_typed_data.type == Dart_TypedData_kUint8); |
| 118 payload_length = payload_message->value.as_typed_data.length; | 115 payload_length = payload_message->value.as_typed_data.length; |
| 119 payload = reinterpret_cast<uint8_t*>(malloc(payload_length)); | 116 payload = reinterpret_cast<uint8_t*>(malloc(payload_length)); |
| 120 memmove(payload, payload_message->value.as_typed_data.values, | 117 memmove(payload, payload_message->value.as_typed_data.values, |
| 121 payload_length); | 118 payload_length); |
| 122 } | 119 } |
| 123 } | 120 } |
| 124 | 121 |
| 125 | |
| 126 void Loader::IOResult::Cleanup() { | 122 void Loader::IOResult::Cleanup() { |
| 127 free(uri); | 123 free(uri); |
| 128 free(resolved_uri); | 124 free(resolved_uri); |
| 129 free(library_uri); | 125 free(library_uri); |
| 130 free(payload); | 126 free(payload); |
| 131 } | 127 } |
| 132 | 128 |
| 133 | |
| 134 // Send the Loader Initialization message to the service isolate. This | 129 // Send the Loader Initialization message to the service isolate. This |
| 135 // message is sent the first time a loader is constructed for an isolate and | 130 // message is sent the first time a loader is constructed for an isolate and |
| 136 // seeds the service isolate with some initial state about this isolate. | 131 // seeds the service isolate with some initial state about this isolate. |
| 137 void Loader::Init(const char* package_root, | 132 void Loader::Init(const char* package_root, |
| 138 const char* packages_file, | 133 const char* packages_file, |
| 139 const char* working_directory, | 134 const char* working_directory, |
| 140 const char* root_script_uri) { | 135 const char* root_script_uri) { |
| 141 // This port delivers loading messages to the service isolate. | 136 // This port delivers loading messages to the service isolate. |
| 142 Dart_Port loader_port = Builtin::LoadPort(); | 137 Dart_Port loader_port = Builtin::LoadPort(); |
| 143 ASSERT(loader_port != ILLEGAL_PORT); | 138 ASSERT(loader_port != ILLEGAL_PORT); |
| 144 | 139 |
| 145 // Keep in sync with loader.dart. | 140 // Keep in sync with loader.dart. |
| 146 const intptr_t _Dart_kInitLoader = 4; | 141 const intptr_t _Dart_kInitLoader = 4; |
| 147 | 142 |
| 148 Dart_Handle request = Dart_NewList(9); | 143 Dart_Handle request = Dart_NewList(9); |
| 149 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 144 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
| 150 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 145 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
| 151 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kInitLoader)); | 146 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kInitLoader)); |
| 152 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 147 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
| 153 Dart_ListSetAt(request, 4, (package_root == NULL) | 148 Dart_ListSetAt(request, 4, |
| 154 ? Dart_Null() | 149 (package_root == NULL) |
| 155 : Dart_NewStringFromCString(package_root)); | 150 ? Dart_Null() |
| 156 Dart_ListSetAt(request, 5, (packages_file == NULL) | 151 : Dart_NewStringFromCString(package_root)); |
| 157 ? Dart_Null() | 152 Dart_ListSetAt(request, 5, |
| 158 : Dart_NewStringFromCString(packages_file)); | 153 (packages_file == NULL) |
| 154 ? Dart_Null() |
| 155 : Dart_NewStringFromCString(packages_file)); |
| 159 Dart_ListSetAt(request, 6, Dart_NewStringFromCString(working_directory)); | 156 Dart_ListSetAt(request, 6, Dart_NewStringFromCString(working_directory)); |
| 160 Dart_ListSetAt(request, 7, (root_script_uri == NULL) | 157 Dart_ListSetAt(request, 7, |
| 161 ? Dart_Null() | 158 (root_script_uri == NULL) |
| 162 : Dart_NewStringFromCString(root_script_uri)); | 159 ? Dart_Null() |
| 160 : Dart_NewStringFromCString(root_script_uri)); |
| 163 Dart_ListSetAt(request, 8, Dart_NewBoolean(Dart_IsReloading())); | 161 Dart_ListSetAt(request, 8, Dart_NewBoolean(Dart_IsReloading())); |
| 164 | 162 |
| 165 | |
| 166 bool success = Dart_Post(loader_port, request); | 163 bool success = Dart_Post(loader_port, request); |
| 167 ASSERT(success); | 164 ASSERT(success); |
| 168 } | 165 } |
| 169 | 166 |
| 170 | |
| 171 void Loader::SendImportExtensionRequest(Dart_Handle url, | 167 void Loader::SendImportExtensionRequest(Dart_Handle url, |
| 172 Dart_Handle library_url) { | 168 Dart_Handle library_url) { |
| 173 // This port delivers loading messages to the service isolate. | 169 // This port delivers loading messages to the service isolate. |
| 174 Dart_Port loader_port = Builtin::LoadPort(); | 170 Dart_Port loader_port = Builtin::LoadPort(); |
| 175 ASSERT(loader_port != ILLEGAL_PORT); | 171 ASSERT(loader_port != ILLEGAL_PORT); |
| 176 | 172 |
| 177 | |
| 178 Dart_Handle request = Dart_NewList(6); | 173 Dart_Handle request = Dart_NewList(6); |
| 179 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 174 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
| 180 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 175 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
| 181 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kImportExtension)); | 176 Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kImportExtension)); |
| 182 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 177 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
| 183 | 178 |
| 184 Dart_ListSetAt(request, 4, url); | 179 Dart_ListSetAt(request, 4, url); |
| 185 Dart_ListSetAt(request, 5, library_url); | 180 Dart_ListSetAt(request, 5, library_url); |
| 186 | 181 |
| 187 if (Dart_Post(loader_port, request)) { | 182 if (Dart_Post(loader_port, request)) { |
| 188 MonitorLocker ml(monitor_); | 183 MonitorLocker ml(monitor_); |
| 189 pending_operations_++; | 184 pending_operations_++; |
| 190 } | 185 } |
| 191 } | 186 } |
| 192 | 187 |
| 193 | |
| 194 // Forward a request from the tag handler to the service isolate. | 188 // Forward a request from the tag handler to the service isolate. |
| 195 void Loader::SendRequest(intptr_t tag, | 189 void Loader::SendRequest(intptr_t tag, |
| 196 Dart_Handle url, | 190 Dart_Handle url, |
| 197 Dart_Handle library_url) { | 191 Dart_Handle library_url) { |
| 198 // This port delivers loading messages to the service isolate. | 192 // This port delivers loading messages to the service isolate. |
| 199 Dart_Port loader_port = Builtin::LoadPort(); | 193 Dart_Port loader_port = Builtin::LoadPort(); |
| 200 ASSERT(loader_port != ILLEGAL_PORT); | 194 ASSERT(loader_port != ILLEGAL_PORT); |
| 201 | 195 |
| 202 Dart_Handle request = Dart_NewList(6); | 196 Dart_Handle request = Dart_NewList(6); |
| 203 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); | 197 Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False()); |
| 204 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); | 198 Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId())); |
| 205 Dart_ListSetAt(request, 2, Dart_NewInteger(tag)); | 199 Dart_ListSetAt(request, 2, Dart_NewInteger(tag)); |
| 206 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); | 200 Dart_ListSetAt(request, 3, Dart_NewSendPort(port_)); |
| 207 | 201 |
| 208 Dart_ListSetAt(request, 4, url); | 202 Dart_ListSetAt(request, 4, url); |
| 209 Dart_ListSetAt(request, 5, library_url); | 203 Dart_ListSetAt(request, 5, library_url); |
| 210 | 204 |
| 211 if (Dart_Post(loader_port, request)) { | 205 if (Dart_Post(loader_port, request)) { |
| 212 MonitorLocker ml(monitor_); | 206 MonitorLocker ml(monitor_); |
| 213 pending_operations_++; | 207 pending_operations_++; |
| 214 } | 208 } |
| 215 } | 209 } |
| 216 | 210 |
| 217 | |
| 218 // Forward a request from the tag handler to the kernel isolate. | 211 // Forward a request from the tag handler to the kernel isolate. |
| 219 // [ tag, send port, url ] | 212 // [ tag, send port, url ] |
| 220 void Loader::SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url) { | 213 void Loader::SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url) { |
| 221 // This port delivers loading messages to the Kernel isolate. | 214 // This port delivers loading messages to the Kernel isolate. |
| 222 Dart_Port kernel_port = Dart_KernelPort(); | 215 Dart_Port kernel_port = Dart_KernelPort(); |
| 223 ASSERT(kernel_port != ILLEGAL_PORT); | 216 ASSERT(kernel_port != ILLEGAL_PORT); |
| 224 | 217 |
| 225 Dart_Handle request = Dart_NewList(3); | 218 Dart_Handle request = Dart_NewList(3); |
| 226 Dart_ListSetAt(request, 0, Dart_NewInteger(tag)); | 219 Dart_ListSetAt(request, 0, Dart_NewInteger(tag)); |
| 227 Dart_ListSetAt(request, 1, Dart_NewSendPort(port_)); | 220 Dart_ListSetAt(request, 1, Dart_NewSendPort(port_)); |
| 228 Dart_ListSetAt(request, 2, url); | 221 Dart_ListSetAt(request, 2, url); |
| 229 if (Dart_Post(kernel_port, request)) { | 222 if (Dart_Post(kernel_port, request)) { |
| 230 MonitorLocker ml(monitor_); | 223 MonitorLocker ml(monitor_); |
| 231 pending_operations_++; | 224 pending_operations_++; |
| 232 } | 225 } |
| 233 } | 226 } |
| 234 | 227 |
| 235 | |
| 236 void Loader::QueueMessage(Dart_CObject* message) { | 228 void Loader::QueueMessage(Dart_CObject* message) { |
| 237 MonitorLocker ml(monitor_); | 229 MonitorLocker ml(monitor_); |
| 238 if (results_length_ == results_capacity_) { | 230 if (results_length_ == results_capacity_) { |
| 239 // Grow to an initial capacity or double in size. | 231 // Grow to an initial capacity or double in size. |
| 240 results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2; | 232 results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2; |
| 241 results_ = reinterpret_cast<IOResult*>( | 233 results_ = reinterpret_cast<IOResult*>( |
| 242 realloc(results_, sizeof(IOResult) * results_capacity_)); | 234 realloc(results_, sizeof(IOResult) * results_capacity_)); |
| 243 ASSERT(results_ != NULL); | 235 ASSERT(results_ != NULL); |
| 244 } | 236 } |
| 245 ASSERT(results_ != NULL); | 237 ASSERT(results_ != NULL); |
| 246 ASSERT(results_length_ < results_capacity_); | 238 ASSERT(results_length_ < results_capacity_); |
| 247 results_[results_length_].Setup(message); | 239 results_[results_length_].Setup(message); |
| 248 results_length_++; | 240 results_length_++; |
| 249 ml.Notify(); | 241 ml.Notify(); |
| 250 } | 242 } |
| 251 | 243 |
| 252 | |
| 253 void Loader::BlockUntilComplete(ProcessResult process_result) { | 244 void Loader::BlockUntilComplete(ProcessResult process_result) { |
| 254 MonitorLocker ml(monitor_); | 245 MonitorLocker ml(monitor_); |
| 255 | 246 |
| 256 while (true) { | 247 while (true) { |
| 257 // If |ProcessQueueLocked| returns false, we've hit an error and should | 248 // If |ProcessQueueLocked| returns false, we've hit an error and should |
| 258 // stop loading. | 249 // stop loading. |
| 259 if (!ProcessQueueLocked(process_result)) { | 250 if (!ProcessQueueLocked(process_result)) { |
| 260 break; | 251 break; |
| 261 } | 252 } |
| 262 | 253 |
| 263 // When |pending_operations_| hits 0, we are done loading. | 254 // When |pending_operations_| hits 0, we are done loading. |
| 264 if (pending_operations_ == 0) { | 255 if (pending_operations_ == 0) { |
| 265 break; | 256 break; |
| 266 } | 257 } |
| 267 | 258 |
| 268 // Wait to be notified about new I/O results. | 259 // Wait to be notified about new I/O results. |
| 269 ml.Wait(); | 260 ml.Wait(); |
| 270 } | 261 } |
| 271 } | 262 } |
| 272 | 263 |
| 273 | |
| 274 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { | 264 static bool LibraryHandleError(Dart_Handle library, Dart_Handle error) { |
| 275 if (!Dart_IsNull(library) && !Dart_IsError(library)) { | 265 if (!Dart_IsNull(library) && !Dart_IsError(library)) { |
| 276 ASSERT(Dart_IsLibrary(library)); | 266 ASSERT(Dart_IsLibrary(library)); |
| 277 Dart_Handle res = Dart_LibraryHandleError(library, error); | 267 Dart_Handle res = Dart_LibraryHandleError(library, error); |
| 278 if (Dart_IsNull(res)) { | 268 if (Dart_IsNull(res)) { |
| 279 // Error was handled by library. | 269 // Error was handled by library. |
| 280 return true; | 270 return true; |
| 281 } | 271 } |
| 282 } | 272 } |
| 283 return false; | 273 return false; |
| 284 } | 274 } |
| 285 | 275 |
| 286 | |
| 287 static bool PathContainsSeparator(const char* path) { | 276 static bool PathContainsSeparator(const char* path) { |
| 288 return (strchr(path, '/') != NULL) || | 277 return (strchr(path, '/') != NULL) || |
| 289 ((strncmp(File::PathSeparator(), "/", 1) != 0) && | 278 ((strncmp(File::PathSeparator(), "/", 1) != 0) && |
| 290 (strstr(path, File::PathSeparator()) != NULL)); | 279 (strstr(path, File::PathSeparator()) != NULL)); |
| 291 } | 280 } |
| 292 | 281 |
| 293 | |
| 294 void Loader::AddDependencyLocked(Loader* loader, const char* resolved_uri) { | 282 void Loader::AddDependencyLocked(Loader* loader, const char* resolved_uri) { |
| 295 MallocGrowableArray<char*>* dependencies = | 283 MallocGrowableArray<char*>* dependencies = |
| 296 loader->isolate_data_->dependencies(); | 284 loader->isolate_data_->dependencies(); |
| 297 if (dependencies == NULL) { | 285 if (dependencies == NULL) { |
| 298 return; | 286 return; |
| 299 } | 287 } |
| 300 dependencies->Add(strdup(resolved_uri)); | 288 dependencies->Add(strdup(resolved_uri)); |
| 301 } | 289 } |
| 302 | 290 |
| 303 | |
| 304 void Loader::ResolveDependenciesAsFilePaths() { | 291 void Loader::ResolveDependenciesAsFilePaths() { |
| 305 IsolateData* isolate_data = | 292 IsolateData* isolate_data = |
| 306 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 293 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
| 307 ASSERT(isolate_data != NULL); | 294 ASSERT(isolate_data != NULL); |
| 308 MallocGrowableArray<char*>* dependencies = isolate_data->dependencies(); | 295 MallocGrowableArray<char*>* dependencies = isolate_data->dependencies(); |
| 309 if (dependencies == NULL) { | 296 if (dependencies == NULL) { |
| 310 return; | 297 return; |
| 311 } | 298 } |
| 312 | 299 |
| 313 for (intptr_t i = 0; i < dependencies->length(); i++) { | 300 for (intptr_t i = 0; i < dependencies->length(); i++) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 324 return; | 311 return; |
| 325 } | 312 } |
| 326 | 313 |
| 327 (*dependencies)[i] = | 314 (*dependencies)[i] = |
| 328 StringUtils::StrNDup(reinterpret_cast<const char*>(scoped_file_path), | 315 StringUtils::StrNDup(reinterpret_cast<const char*>(scoped_file_path), |
| 329 scoped_file_path_length); | 316 scoped_file_path_length); |
| 330 free(resolved_uri); | 317 free(resolved_uri); |
| 331 } | 318 } |
| 332 } | 319 } |
| 333 | 320 |
| 334 | |
| 335 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) { | 321 bool Loader::ProcessResultLocked(Loader* loader, Loader::IOResult* result) { |
| 336 // We have to copy everything we care about out of |result| because after | 322 // We have to copy everything we care about out of |result| because after |
| 337 // dropping the lock below |result| may no longer valid. | 323 // dropping the lock below |result| may no longer valid. |
| 338 Dart_Handle uri = | 324 Dart_Handle uri = |
| 339 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); | 325 Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri)); |
| 340 Dart_Handle resolved_uri = | 326 Dart_Handle resolved_uri = |
| 341 Dart_NewStringFromCString(reinterpret_cast<char*>(result->resolved_uri)); | 327 Dart_NewStringFromCString(reinterpret_cast<char*>(result->resolved_uri)); |
| 342 Dart_Handle library_uri = Dart_Null(); | 328 Dart_Handle library_uri = Dart_Null(); |
| 343 if (result->library_uri != NULL) { | 329 if (result->library_uri != NULL) { |
| 344 library_uri = | 330 library_uri = |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 if (Dart_IsError(dart_result)) { | 454 if (Dart_IsError(dart_result)) { |
| 469 // Remember the error if we encountered one. | 455 // Remember the error if we encountered one. |
| 470 loader->error_ = dart_result; | 456 loader->error_ = dart_result; |
| 471 return false; | 457 return false; |
| 472 } | 458 } |
| 473 } | 459 } |
| 474 | 460 |
| 475 return true; | 461 return true; |
| 476 } | 462 } |
| 477 | 463 |
| 478 | |
| 479 bool Loader::ProcessPayloadResultLocked(Loader* loader, | 464 bool Loader::ProcessPayloadResultLocked(Loader* loader, |
| 480 Loader::IOResult* result) { | 465 Loader::IOResult* result) { |
| 481 // A negative result tag indicates a loading error occurred in the service | 466 // A negative result tag indicates a loading error occurred in the service |
| 482 // isolate. The payload is a C string of the error message. | 467 // isolate. The payload is a C string of the error message. |
| 483 if (result->tag < 0) { | 468 if (result->tag < 0) { |
| 484 Dart_Handle error = | 469 Dart_Handle error = |
| 485 Dart_NewStringFromUTF8(result->payload, result->payload_length); | 470 Dart_NewStringFromUTF8(result->payload, result->payload_length); |
| 486 loader->error_ = Dart_NewUnhandledExceptionError(error); | 471 loader->error_ = Dart_NewUnhandledExceptionError(error); |
| 487 return false; | 472 return false; |
| 488 } | 473 } |
| 489 loader->payload_length_ = result->payload_length; | 474 loader->payload_length_ = result->payload_length; |
| 490 loader->payload_ = | 475 loader->payload_ = |
| 491 reinterpret_cast<uint8_t*>(::malloc(loader->payload_length_)); | 476 reinterpret_cast<uint8_t*>(::malloc(loader->payload_length_)); |
| 492 memmove(loader->payload_, result->payload, loader->payload_length_); | 477 memmove(loader->payload_, result->payload, loader->payload_length_); |
| 493 return true; | 478 return true; |
| 494 } | 479 } |
| 495 | 480 |
| 496 | |
| 497 bool Loader::ProcessQueueLocked(ProcessResult process_result) { | 481 bool Loader::ProcessQueueLocked(ProcessResult process_result) { |
| 498 bool hit_error = false; | 482 bool hit_error = false; |
| 499 for (intptr_t i = 0; i < results_length(); i++) { | 483 for (intptr_t i = 0; i < results_length(); i++) { |
| 500 if (!hit_error) { | 484 if (!hit_error) { |
| 501 hit_error = !(*process_result)(this, &results_[i]); | 485 hit_error = !(*process_result)(this, &results_[i]); |
| 502 } | 486 } |
| 503 pending_operations_--; | 487 pending_operations_--; |
| 504 ASSERT(hit_error || (pending_operations_ >= 0)); | 488 ASSERT(hit_error || (pending_operations_ >= 0)); |
| 505 results_[i].Cleanup(); | 489 results_[i].Cleanup(); |
| 506 } | 490 } |
| 507 results_length_ = 0; | 491 results_length_ = 0; |
| 508 return !hit_error; | 492 return !hit_error; |
| 509 } | 493 } |
| 510 | 494 |
| 511 | |
| 512 void Loader::InitForSnapshot(const char* snapshot_uri) { | 495 void Loader::InitForSnapshot(const char* snapshot_uri) { |
| 513 IsolateData* isolate_data = | 496 IsolateData* isolate_data = |
| 514 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 497 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
| 515 ASSERT(isolate_data != NULL); | 498 ASSERT(isolate_data != NULL); |
| 516 ASSERT(!isolate_data->HasLoader()); | 499 ASSERT(!isolate_data->HasLoader()); |
| 517 // Setup a loader. The constructor does a bunch of leg work. | 500 // Setup a loader. The constructor does a bunch of leg work. |
| 518 Loader* loader = new Loader(isolate_data); | 501 Loader* loader = new Loader(isolate_data); |
| 519 // Send the init message. | 502 // Send the init message. |
| 520 loader->Init(isolate_data->package_root, isolate_data->packages_file, | 503 loader->Init(isolate_data->package_root, isolate_data->packages_file, |
| 521 DartUtils::original_working_directory, snapshot_uri); | 504 DartUtils::original_working_directory, snapshot_uri); |
| 522 // Destroy the loader. The destructor does a bunch of leg work. | 505 // Destroy the loader. The destructor does a bunch of leg work. |
| 523 delete loader; | 506 delete loader; |
| 524 } | 507 } |
| 525 | 508 |
| 526 | |
| 527 #define RETURN_ERROR(result) \ | 509 #define RETURN_ERROR(result) \ |
| 528 if (Dart_IsError(result)) return result; | 510 if (Dart_IsError(result)) return result; |
| 529 | 511 |
| 530 Dart_Handle Loader::ReloadNativeExtensions() { | 512 Dart_Handle Loader::ReloadNativeExtensions() { |
| 531 Dart_Handle scheme = | 513 Dart_Handle scheme = |
| 532 Dart_NewStringFromCString(DartUtils::kDartExtensionScheme); | 514 Dart_NewStringFromCString(DartUtils::kDartExtensionScheme); |
| 533 Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme); | 515 Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme); |
| 534 RETURN_ERROR(extension_imports); | 516 RETURN_ERROR(extension_imports); |
| 535 | 517 |
| 536 intptr_t length = -1; | 518 intptr_t length = -1; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 561 } | 543 } |
| 562 | 544 |
| 563 result = Extensions::LoadExtension(lib_path, extension_path, importer); | 545 result = Extensions::LoadExtension(lib_path, extension_path, importer); |
| 564 free(lib_path); | 546 free(lib_path); |
| 565 RETURN_ERROR(result); | 547 RETURN_ERROR(result); |
| 566 } | 548 } |
| 567 | 549 |
| 568 return Dart_True(); | 550 return Dart_True(); |
| 569 } | 551 } |
| 570 | 552 |
| 571 | |
| 572 Dart_Handle Loader::SendAndProcessReply(intptr_t tag, | 553 Dart_Handle Loader::SendAndProcessReply(intptr_t tag, |
| 573 Dart_Handle url, | 554 Dart_Handle url, |
| 574 uint8_t** payload, | 555 uint8_t** payload, |
| 575 intptr_t* payload_length) { | 556 intptr_t* payload_length) { |
| 576 IsolateData* isolate_data = | 557 IsolateData* isolate_data = |
| 577 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); | 558 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); |
| 578 ASSERT(isolate_data != NULL); | 559 ASSERT(isolate_data != NULL); |
| 579 ASSERT(!isolate_data->HasLoader()); | 560 ASSERT(!isolate_data->HasLoader()); |
| 580 Loader* loader = NULL; | 561 Loader* loader = NULL; |
| 581 | 562 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 602 // Destroy the loader. The destructor does a bunch of leg work. | 583 // Destroy the loader. The destructor does a bunch of leg work. |
| 603 delete loader; | 584 delete loader; |
| 604 | 585 |
| 605 // An error occurred during loading. | 586 // An error occurred during loading. |
| 606 if (!Dart_IsNull(error)) { | 587 if (!Dart_IsNull(error)) { |
| 607 return error; | 588 return error; |
| 608 } | 589 } |
| 609 return Dart_Null(); | 590 return Dart_Null(); |
| 610 } | 591 } |
| 611 | 592 |
| 612 | |
| 613 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, | 593 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, |
| 614 uint8_t** payload, | 594 uint8_t** payload, |
| 615 intptr_t* payload_length) { | 595 intptr_t* payload_length) { |
| 616 return SendAndProcessReply(Dart_kScriptTag, url, payload, payload_length); | 596 return SendAndProcessReply(Dart_kScriptTag, url, payload, payload_length); |
| 617 } | 597 } |
| 618 | 598 |
| 619 | |
| 620 Dart_Handle Loader::ResolveAsFilePath(Dart_Handle url, | 599 Dart_Handle Loader::ResolveAsFilePath(Dart_Handle url, |
| 621 uint8_t** payload, | 600 uint8_t** payload, |
| 622 intptr_t* payload_length) { | 601 intptr_t* payload_length) { |
| 623 return SendAndProcessReply(_Dart_kResolveAsFilePath, url, payload, | 602 return SendAndProcessReply(_Dart_kResolveAsFilePath, url, payload, |
| 624 payload_length); | 603 payload_length); |
| 625 } | 604 } |
| 626 | 605 |
| 627 #if defined(DART_PRECOMPILED_RUNTIME) | 606 #if defined(DART_PRECOMPILED_RUNTIME) |
| 628 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, | 607 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, |
| 629 Dart_Handle library, | 608 Dart_Handle library, |
| 630 Dart_Handle url) { | 609 Dart_Handle url) { |
| 631 return Dart_Null(); | 610 return Dart_Null(); |
| 632 } | 611 } |
| 633 | 612 |
| 634 | |
| 635 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, | 613 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, |
| 636 Dart_Handle library, | 614 Dart_Handle library, |
| 637 Dart_Handle url, | 615 Dart_Handle url, |
| 638 const char* library_url_string, | 616 const char* library_url_string, |
| 639 const char* url_string) { | 617 const char* url_string) { |
| 640 return Dart_Null(); | 618 return Dart_Null(); |
| 641 } | 619 } |
| 642 #else | 620 #else |
| 643 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, | 621 Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, |
| 644 Dart_Handle library, | 622 Dart_Handle library, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } | 720 } |
| 743 ASSERT(loader != NULL); | 721 ASSERT(loader != NULL); |
| 744 ASSERT(isolate_data->HasLoader()); | 722 ASSERT(isolate_data->HasLoader()); |
| 745 | 723 |
| 746 if (DartUtils::IsDartExtensionSchemeURL(url_string)) { | 724 if (DartUtils::IsDartExtensionSchemeURL(url_string)) { |
| 747 loader->SendImportExtensionRequest(url, Dart_LibraryUrl(library)); | 725 loader->SendImportExtensionRequest(url, Dart_LibraryUrl(library)); |
| 748 } else { | 726 } else { |
| 749 if (Dart_KernelIsolateIsRunning()) { | 727 if (Dart_KernelIsolateIsRunning()) { |
| 750 loader->SendKernelRequest(tag, url); | 728 loader->SendKernelRequest(tag, url); |
| 751 } else { | 729 } else { |
| 752 loader->SendRequest(tag, url, (library != Dart_Null()) | 730 loader->SendRequest( |
| 753 ? Dart_LibraryUrl(library) | 731 tag, url, |
| 754 : Dart_Null()); | 732 (library != Dart_Null()) ? Dart_LibraryUrl(library) : Dart_Null()); |
| 755 } | 733 } |
| 756 } | 734 } |
| 757 | 735 |
| 758 if (blocking_call) { | 736 if (blocking_call) { |
| 759 // The outer invocation of the tag handler will block here until all nested | 737 // The outer invocation of the tag handler will block here until all nested |
| 760 // invocations complete. | 738 // invocations complete. |
| 761 loader->BlockUntilComplete(ProcessResultLocked); | 739 loader->BlockUntilComplete(ProcessResultLocked); |
| 762 | 740 |
| 763 // Remember the error (if any). | 741 // Remember the error (if any). |
| 764 Dart_Handle error = loader->error(); | 742 Dart_Handle error = loader->error(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 788 // Finalize loading. This will complete any futures for completed deferred | 766 // Finalize loading. This will complete any futures for completed deferred |
| 789 // loads. | 767 // loads. |
| 790 error = Dart_FinalizeLoading(true); | 768 error = Dart_FinalizeLoading(true); |
| 791 if (Dart_IsError(error)) { | 769 if (Dart_IsError(error)) { |
| 792 return error; | 770 return error; |
| 793 } | 771 } |
| 794 } | 772 } |
| 795 return Dart_Null(); | 773 return Dart_Null(); |
| 796 } | 774 } |
| 797 | 775 |
| 798 | |
| 799 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, | 776 Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag, |
| 800 Dart_Handle library, | 777 Dart_Handle library, |
| 801 Dart_Handle url, | 778 Dart_Handle url, |
| 802 const char* library_url_string, | 779 const char* library_url_string, |
| 803 const char* url_string) { | 780 const char* url_string) { |
| 804 // Handle canonicalization, 'import' and 'part' of 'dart:' libraries. | 781 // Handle canonicalization, 'import' and 'part' of 'dart:' libraries. |
| 805 if (tag == Dart_kCanonicalizeUrl) { | 782 if (tag == Dart_kCanonicalizeUrl) { |
| 806 // These will be handled internally. | 783 // These will be handled internally. |
| 807 return url; | 784 return url; |
| 808 } else if (tag == Dart_kImportTag) { | 785 } else if (tag == Dart_kImportTag) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 832 free(part_uri); | 809 free(part_uri); |
| 833 return Dart_LoadSource(library, part_uri_obj, Dart_Null(), | 810 return Dart_LoadSource(library, part_uri_obj, Dart_Null(), |
| 834 Builtin::PartSource(id, url_string), 0, 0); | 811 Builtin::PartSource(id, url_string), 0, 0); |
| 835 } | 812 } |
| 836 // All cases should have been handled above. | 813 // All cases should have been handled above. |
| 837 UNREACHABLE(); | 814 UNREACHABLE(); |
| 838 return Dart_Null(); | 815 return Dart_Null(); |
| 839 } | 816 } |
| 840 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 817 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| 841 | 818 |
| 842 | |
| 843 void Loader::InitOnce() { | 819 void Loader::InitOnce() { |
| 844 loader_infos_lock_ = new Mutex(); | 820 loader_infos_lock_ = new Mutex(); |
| 845 } | 821 } |
| 846 | 822 |
| 847 | |
| 848 Mutex* Loader::loader_infos_lock_; | 823 Mutex* Loader::loader_infos_lock_; |
| 849 Loader::LoaderInfo* Loader::loader_infos_ = NULL; | 824 Loader::LoaderInfo* Loader::loader_infos_ = NULL; |
| 850 intptr_t Loader::loader_infos_length_ = 0; | 825 intptr_t Loader::loader_infos_length_ = 0; |
| 851 intptr_t Loader::loader_infos_capacity_ = 0; | 826 intptr_t Loader::loader_infos_capacity_ = 0; |
| 852 | 827 |
| 853 | |
| 854 // Add a mapping from |port| to |isolate_data| (really the loader). When a | 828 // Add a mapping from |port| to |isolate_data| (really the loader). When a |
| 855 // native message arrives, we use this map to report the I/O result to the | 829 // native message arrives, we use this map to report the I/O result to the |
| 856 // correct loader. | 830 // correct loader. |
| 857 // This happens whenever an isolate begins loading. | 831 // This happens whenever an isolate begins loading. |
| 858 void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) { | 832 void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) { |
| 859 MutexLocker ml(loader_infos_lock_); | 833 MutexLocker ml(loader_infos_lock_); |
| 860 ASSERT(LoaderForLocked(port) == NULL); | 834 ASSERT(LoaderForLocked(port) == NULL); |
| 861 if (loader_infos_length_ == loader_infos_capacity_) { | 835 if (loader_infos_length_ == loader_infos_capacity_) { |
| 862 // Grow to an initial capacity or double in size. | 836 // Grow to an initial capacity or double in size. |
| 863 loader_infos_capacity_ = | 837 loader_infos_capacity_ = |
| 864 (loader_infos_capacity_ == 0) ? 4 : loader_infos_capacity_ * 2; | 838 (loader_infos_capacity_ == 0) ? 4 : loader_infos_capacity_ * 2; |
| 865 loader_infos_ = reinterpret_cast<Loader::LoaderInfo*>(realloc( | 839 loader_infos_ = reinterpret_cast<Loader::LoaderInfo*>(realloc( |
| 866 loader_infos_, sizeof(Loader::LoaderInfo) * loader_infos_capacity_)); | 840 loader_infos_, sizeof(Loader::LoaderInfo) * loader_infos_capacity_)); |
| 867 ASSERT(loader_infos_ != NULL); | 841 ASSERT(loader_infos_ != NULL); |
| 868 // Initialize new entries. | 842 // Initialize new entries. |
| 869 for (intptr_t i = loader_infos_length_; i < loader_infos_capacity_; i++) { | 843 for (intptr_t i = loader_infos_length_; i < loader_infos_capacity_; i++) { |
| 870 loader_infos_[i].port = ILLEGAL_PORT; | 844 loader_infos_[i].port = ILLEGAL_PORT; |
| 871 loader_infos_[i].isolate_data = NULL; | 845 loader_infos_[i].isolate_data = NULL; |
| 872 } | 846 } |
| 873 } | 847 } |
| 874 ASSERT(loader_infos_length_ < loader_infos_capacity_); | 848 ASSERT(loader_infos_length_ < loader_infos_capacity_); |
| 875 loader_infos_[loader_infos_length_].port = port; | 849 loader_infos_[loader_infos_length_].port = port; |
| 876 loader_infos_[loader_infos_length_].isolate_data = isolate_data; | 850 loader_infos_[loader_infos_length_].isolate_data = isolate_data; |
| 877 loader_infos_length_++; | 851 loader_infos_length_++; |
| 878 ASSERT(LoaderForLocked(port) != NULL); | 852 ASSERT(LoaderForLocked(port) != NULL); |
| 879 } | 853 } |
| 880 | 854 |
| 881 | |
| 882 // Remove |port| from the map. | 855 // Remove |port| from the map. |
| 883 // This happens once an isolate has finished loading. | 856 // This happens once an isolate has finished loading. |
| 884 void Loader::RemoveLoader(Dart_Port port) { | 857 void Loader::RemoveLoader(Dart_Port port) { |
| 885 MutexLocker ml(loader_infos_lock_); | 858 MutexLocker ml(loader_infos_lock_); |
| 886 const intptr_t index = LoaderIndexFor(port); | 859 const intptr_t index = LoaderIndexFor(port); |
| 887 ASSERT(index >= 0); | 860 ASSERT(index >= 0); |
| 888 const intptr_t last = loader_infos_length_ - 1; | 861 const intptr_t last = loader_infos_length_ - 1; |
| 889 ASSERT(last >= 0); | 862 ASSERT(last >= 0); |
| 890 if (index != last) { | 863 if (index != last) { |
| 891 // Swap with the tail. | 864 // Swap with the tail. |
| 892 loader_infos_[index] = loader_infos_[last]; | 865 loader_infos_[index] = loader_infos_[last]; |
| 893 } | 866 } |
| 894 loader_infos_length_--; | 867 loader_infos_length_--; |
| 895 } | 868 } |
| 896 | 869 |
| 897 | |
| 898 intptr_t Loader::LoaderIndexFor(Dart_Port port) { | 870 intptr_t Loader::LoaderIndexFor(Dart_Port port) { |
| 899 for (intptr_t i = 0; i < loader_infos_length_; i++) { | 871 for (intptr_t i = 0; i < loader_infos_length_; i++) { |
| 900 if (loader_infos_[i].port == port) { | 872 if (loader_infos_[i].port == port) { |
| 901 return i; | 873 return i; |
| 902 } | 874 } |
| 903 } | 875 } |
| 904 return -1; | 876 return -1; |
| 905 } | 877 } |
| 906 | 878 |
| 907 | |
| 908 Loader* Loader::LoaderForLocked(Dart_Port port) { | 879 Loader* Loader::LoaderForLocked(Dart_Port port) { |
| 909 intptr_t index = LoaderIndexFor(port); | 880 intptr_t index = LoaderIndexFor(port); |
| 910 if (index < 0) { | 881 if (index < 0) { |
| 911 return NULL; | 882 return NULL; |
| 912 } | 883 } |
| 913 return loader_infos_[index].isolate_data->loader(); | 884 return loader_infos_[index].isolate_data->loader(); |
| 914 } | 885 } |
| 915 | 886 |
| 916 | |
| 917 Loader* Loader::LoaderFor(Dart_Port port) { | 887 Loader* Loader::LoaderFor(Dart_Port port) { |
| 918 MutexLocker ml(loader_infos_lock_); | 888 MutexLocker ml(loader_infos_lock_); |
| 919 return LoaderForLocked(port); | 889 return LoaderForLocked(port); |
| 920 } | 890 } |
| 921 | 891 |
| 922 | |
| 923 void Loader::NativeMessageHandler(Dart_Port dest_port_id, | 892 void Loader::NativeMessageHandler(Dart_Port dest_port_id, |
| 924 Dart_CObject* message) { | 893 Dart_CObject* message) { |
| 925 MutexLocker ml(loader_infos_lock_); | 894 MutexLocker ml(loader_infos_lock_); |
| 926 Loader* loader = LoaderForLocked(dest_port_id); | 895 Loader* loader = LoaderForLocked(dest_port_id); |
| 927 if (loader == NULL) { | 896 if (loader == NULL) { |
| 928 return; | 897 return; |
| 929 } | 898 } |
| 930 loader->QueueMessage(message); | 899 loader->QueueMessage(message); |
| 931 } | 900 } |
| 932 | 901 |
| 933 } // namespace bin | 902 } // namespace bin |
| 934 } // namespace dart | 903 } // namespace dart |
| OLD | NEW |