Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart.h" | 8 #include "vm/dart.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 static void ThrowIsolateSpawnException(const String& message) { | 121 static void ThrowIsolateSpawnException(const String& message) { |
| 122 const Array& args = Array::Handle(Array::New(1)); | 122 const Array& args = Array::Handle(Array::New(1)); |
| 123 args.SetAt(0, message); | 123 args.SetAt(0, message); |
| 124 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); | 124 Exceptions::ThrowByType(Exceptions::kIsolateSpawn, args); |
| 125 } | 125 } |
| 126 | 126 |
| 127 | 127 |
| 128 static bool CanonicalizeUri(Isolate* isolate, | |
| 129 const Library& library, | |
| 130 const String& uri, | |
| 131 char** canonical_uri, | |
| 132 char** error) { | |
| 133 Zone* zone = isolate->current_zone(); | |
| 134 bool retval = false; | |
| 135 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | |
| 136 if (handler != NULL) { | |
| 137 Dart_EnterScope(); | |
| 138 Dart_Handle result = handler(Dart_kCanonicalizeUrl, | |
| 139 Api::NewHandle(isolate, library.raw()), | |
| 140 Api::NewHandle(isolate, uri.raw())); | |
| 141 const Object& obj = Object::Handle(Api::UnwrapHandle(result)); | |
| 142 if (obj.IsString()) { | |
| 143 *canonical_uri = zone->MakeCopyOfString(String::Cast(obj).ToCString()); | |
| 144 retval = true; | |
| 145 } else if (obj.IsError()) { | |
| 146 Error& error_obj = Error::Handle(); | |
| 147 error_obj ^= obj.raw(); | |
| 148 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s", | |
| 149 uri.ToCString(), error_obj.ToErrorCString()); | |
| 150 } else { | |
| 151 *error = zone->PrintToString("Unable to canonicalize uri '%s': " | |
| 152 "library tag handler returned wrong type", | |
| 153 uri.ToCString()); | |
| 154 } | |
| 155 Dart_ExitScope(); | |
| 156 } else { | |
| 157 *error = zone->PrintToString( | |
| 158 "Unable to canonicalize uri '%s': no library tag handler found.", | |
| 159 uri.ToCString()); | |
| 160 } | |
| 161 return retval; | |
| 162 } | |
| 163 | |
| 164 | |
| 165 static bool CreateIsolate(Isolate* parent_isolate, | 128 static bool CreateIsolate(Isolate* parent_isolate, |
| 166 IsolateSpawnState* state, | 129 IsolateSpawnState* state, |
| 167 char** error) { | 130 char** error) { |
| 168 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); | 131 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); |
| 169 if (callback == NULL) { | 132 if (callback == NULL) { |
| 170 *error = strdup("Null callback specified for isolate creation\n"); | 133 *error = strdup("Null callback specified for isolate creation\n"); |
| 171 return false; | 134 return false; |
| 172 } | 135 } |
| 173 | 136 |
| 174 Dart_IsolateFlags api_flags; | 137 Dart_IsolateFlags api_flags; |
| 175 state->isolate_flags()->CopyTo(&api_flags); | 138 state->isolate_flags()->CopyTo(&api_flags); |
| 176 | 139 |
| 177 void* init_data = parent_isolate->init_callback_data(); | 140 void* init_data = parent_isolate->init_callback_data(); |
| 178 Isolate* child_isolate = reinterpret_cast<Isolate*>( | 141 Isolate* child_isolate = reinterpret_cast<Isolate*>( |
| 179 (callback)(state->script_url(), | 142 (callback)(state->script_url(), |
| 180 state->function_name(), | 143 state->function_name(), |
| 181 state->package_root(), | 144 state->package_root(), |
| 145 state->package_map(), | |
| 182 &api_flags, | 146 &api_flags, |
| 183 init_data, | 147 init_data, |
| 184 error)); | 148 error)); |
| 185 if (child_isolate == NULL) { | 149 if (child_isolate == NULL) { |
| 186 return false; | 150 return false; |
| 187 } | 151 } |
| 188 if (!state->is_spawn_uri()) { | 152 if (!state->is_spawn_uri()) { |
| 189 // For isolates spawned using the spawn semantics we set | 153 // For isolates spawned using the spawn semantics we set |
| 190 // the origin_id to the origin_id of the parent isolate. | 154 // the origin_id to the origin_id of the parent isolate. |
| 191 child_isolate->set_origin_id(parent_isolate->origin_id()); | 155 child_isolate->set_origin_id(parent_isolate->origin_id()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 return Object::null(); | 216 return Object::null(); |
| 253 } | 217 } |
| 254 } | 218 } |
| 255 const String& msg = String::Handle(String::New( | 219 const String& msg = String::Handle(String::New( |
| 256 "Isolate.spawn expects to be passed a static or top-level function")); | 220 "Isolate.spawn expects to be passed a static or top-level function")); |
| 257 Exceptions::ThrowArgumentError(msg); | 221 Exceptions::ThrowArgumentError(msg); |
| 258 return Object::null(); | 222 return Object::null(); |
| 259 } | 223 } |
| 260 | 224 |
| 261 | 225 |
| 226 static char* String2UTF8(const String& str) { | |
| 227 intptr_t len = Utf8::Length(str); | |
| 228 char* result = new char[len + 1]; | |
| 229 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); | |
| 230 result[len] = 0; | |
| 231 | |
| 232 return result; | |
| 233 } | |
| 234 | |
| 235 | |
| 236 static char* CanonicalizeUri(Isolate* isolate, | |
| 237 const Library& library, | |
|
Lasse Reichstein Nielsen
2015/10/12 09:34:44
Indentation is off-by-1.
Ivan Posva
2015/10/12 16:05:22
Done.
| |
| 238 const String& uri, | |
| 239 char** error) { | |
| 240 char* result = NULL; | |
| 241 Zone* zone = isolate->current_zone(); | |
| 242 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | |
| 243 if (handler != NULL) { | |
| 244 Dart_EnterScope(); | |
| 245 Dart_Handle handle = handler(Dart_kCanonicalizeUrl, | |
| 246 Api::NewHandle(isolate, library.raw()), | |
| 247 Api::NewHandle(isolate, uri.raw())); | |
| 248 const Object& obj = Object::Handle(Api::UnwrapHandle(handle)); | |
| 249 if (obj.IsString()) { | |
| 250 result = String2UTF8(String::Cast(obj)); | |
| 251 } else if (obj.IsError()) { | |
| 252 Error& error_obj = Error::Handle(); | |
| 253 error_obj ^= obj.raw(); | |
| 254 *error = zone->PrintToString("Unable to canonicalize uri '%s': %s", | |
| 255 uri.ToCString(), error_obj.ToErrorCString()); | |
| 256 } else { | |
| 257 *error = zone->PrintToString("Unable to canonicalize uri '%s': " | |
| 258 "library tag handler returned wrong type", | |
| 259 uri.ToCString()); | |
| 260 } | |
| 261 Dart_ExitScope(); | |
| 262 } else { | |
| 263 *error = zone->PrintToString( | |
| 264 "Unable to canonicalize uri '%s': no library tag handler found.", | |
| 265 uri.ToCString()); | |
| 266 } | |
| 267 return result; | |
| 268 } | |
| 269 | |
| 270 | |
| 262 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { | 271 DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 12) { |
| 263 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 272 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 264 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); | 273 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1)); |
| 265 | 274 |
| 266 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); | 275 GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2)); |
| 267 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); | 276 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3)); |
| 268 | 277 |
| 269 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); | 278 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); |
| 270 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); | 279 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); |
| 271 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); | 280 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); |
| 272 | 281 |
| 273 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); | 282 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); |
| 274 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); | 283 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); |
| 275 | 284 |
| 276 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); | 285 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); |
| 277 | 286 |
| 278 GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10)); | 287 GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10)); |
| 279 GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11)); | 288 GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11)); |
| 280 | 289 |
| 281 | 290 |
| 282 // Canonicalize the uri with respect to the current isolate. | 291 // Canonicalize the uri with respect to the current isolate. |
| 283 char* error = NULL; | |
| 284 char* canonical_uri = NULL; | |
| 285 const Library& root_lib = | 292 const Library& root_lib = |
| 286 Library::Handle(isolate->object_store()->root_library()); | 293 Library::Handle(isolate->object_store()->root_library()); |
| 287 if (!CanonicalizeUri(isolate, root_lib, uri, | 294 char* error = NULL; |
| 288 &canonical_uri, &error)) { | 295 char* canonical_uri = CanonicalizeUri(isolate, root_lib, uri, &error); |
| 296 if (canonical_uri == NULL) { | |
| 289 const String& msg = String::Handle(String::New(error)); | 297 const String& msg = String::Handle(String::New(error)); |
| 290 ThrowIsolateSpawnException(msg); | 298 ThrowIsolateSpawnException(msg); |
| 291 } | 299 } |
| 292 | 300 |
| 293 char* utf8_package_root = NULL; | 301 char* utf8_package_root = |
| 294 if (!package_root.IsNull()) { | 302 package_root.IsNull() ? NULL : String2UTF8(package_root); |
| 295 const intptr_t len = Utf8::Length(package_root); | 303 |
| 296 utf8_package_root = zone->Alloc<char>(len + 1); | 304 char** utf8_package_map = NULL; |
| 297 package_root.ToUTF8(reinterpret_cast<uint8_t*>(utf8_package_root), len); | 305 if (!packages.IsNull()) { |
| 298 utf8_package_root[len] = '\0'; | 306 intptr_t len = packages.Length(); |
| 307 utf8_package_map = new char*[len + 1]; | |
| 308 | |
| 309 Object& entry = Object::Handle(); | |
| 310 for (intptr_t i = 0; i < len; i++) { | |
| 311 entry = packages.At(i); | |
| 312 if (!entry.IsString()) { | |
| 313 const String& msg = String::Handle(String::NewFormatted( | |
| 314 "Bad value in package map: %s", entry.ToCString())); | |
| 315 ThrowIsolateSpawnException(msg); | |
| 316 } | |
| 317 utf8_package_map[i] = String2UTF8(String::Cast(entry)); | |
| 318 } | |
| 319 // NULL terminated array. | |
| 320 utf8_package_map[len] = NULL; | |
| 299 } | 321 } |
| 300 | 322 |
| 301 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); | 323 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); |
| 302 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); | 324 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); |
| 303 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); | 325 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); |
| 304 | 326 |
| 305 IsolateSpawnState* state = new IsolateSpawnState(port.Id(), | 327 IsolateSpawnState* state = new IsolateSpawnState( |
| 306 canonical_uri, | 328 port.Id(), |
| 307 utf8_package_root, | 329 canonical_uri, |
| 308 args, | 330 utf8_package_root, |
| 309 message, | 331 const_cast<const char**>(utf8_package_map), |
| 310 paused.value(), | 332 args, |
| 311 fatal_errors, | 333 message, |
| 312 on_exit_port, | 334 paused.value(), |
| 313 on_error_port); | 335 fatal_errors, |
| 336 on_exit_port, | |
| 337 on_error_port); | |
| 314 // If we were passed a value then override the default flags state for | 338 // If we were passed a value then override the default flags state for |
| 315 // checked mode. | 339 // checked mode. |
| 316 if (!checked.IsNull()) { | 340 if (!checked.IsNull()) { |
| 317 state->isolate_flags()->set_checked(checked.value()); | 341 state->isolate_flags()->set_checked(checked.value()); |
| 318 } | 342 } |
| 319 | 343 |
| 320 Spawn(isolate, state); | 344 Spawn(isolate, state); |
| 321 return Object::null(); | 345 return Object::null(); |
| 322 } | 346 } |
| 323 | 347 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 344 MessageWriter writer(&data, &allocator, false); | 368 MessageWriter writer(&data, &allocator, false); |
| 345 writer.WriteMessage(msg); | 369 writer.WriteMessage(msg); |
| 346 | 370 |
| 347 PortMap::PostMessage(new Message(port.Id(), | 371 PortMap::PostMessage(new Message(port.Id(), |
| 348 data, writer.BytesWritten(), | 372 data, writer.BytesWritten(), |
| 349 Message::kOOBPriority)); | 373 Message::kOOBPriority)); |
| 350 return Object::null(); | 374 return Object::null(); |
| 351 } | 375 } |
| 352 | 376 |
| 353 } // namespace dart | 377 } // namespace dart |
| OLD | NEW |