| 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 "include/dart_native_api.h" | 5 #include "include/dart_native_api.h" |
| 6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
| 7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/dart.h" | 9 #include "vm/dart.h" |
| 10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 return; | 151 return; |
| 152 } | 152 } |
| 153 | 153 |
| 154 Dart_IsolateFlags api_flags; | 154 Dart_IsolateFlags api_flags; |
| 155 state_->isolate_flags()->CopyTo(&api_flags); | 155 state_->isolate_flags()->CopyTo(&api_flags); |
| 156 | 156 |
| 157 Isolate* isolate = reinterpret_cast<Isolate*>( | 157 Isolate* isolate = reinterpret_cast<Isolate*>( |
| 158 (callback)(state_->script_url(), | 158 (callback)(state_->script_url(), |
| 159 state_->function_name(), | 159 state_->function_name(), |
| 160 state_->package_root(), | 160 state_->package_root(), |
| 161 state_->package_map(), | 161 state_->package_config(), |
| 162 &api_flags, | 162 &api_flags, |
| 163 state_->init_data(), | 163 state_->init_data(), |
| 164 &error)); | 164 &error)); |
| 165 state_->DecrementSpawnCount(); | 165 state_->DecrementSpawnCount(); |
| 166 if (isolate == NULL) { | 166 if (isolate == NULL) { |
| 167 ReportError(error); | 167 ReportError(error); |
| 168 delete state_; | 168 delete state_; |
| 169 state_ = NULL; | 169 state_ = NULL; |
| 170 free(error); | 170 free(error); |
| 171 return; | 171 return; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 195 // could report the error. Ignore. | 195 // could report the error. Ignore. |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 | 198 |
| 199 IsolateSpawnState* state_; | 199 IsolateSpawnState* state_; |
| 200 | 200 |
| 201 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask); | 201 DISALLOW_COPY_AND_ASSIGN(SpawnIsolateTask); |
| 202 }; | 202 }; |
| 203 | 203 |
| 204 | 204 |
| 205 DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 7) { | 205 static const char* String2UTF8(const String& str) { |
| 206 intptr_t len = Utf8::Length(str); |
| 207 char* result = new char[len + 1]; |
| 208 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); |
| 209 result[len] = 0; |
| 210 |
| 211 return result; |
| 212 } |
| 213 |
| 214 |
| 215 DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 9) { |
| 206 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 216 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 207 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(1)); | 217 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(1)); |
| 208 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2)); | 218 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2)); |
| 209 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(3)); | 219 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(3)); |
| 210 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(4)); | 220 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(4)); |
| 211 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); | 221 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); |
| 212 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); | 222 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); |
| 223 GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(7)); |
| 224 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8)); |
| 213 | 225 |
| 214 if (closure.IsClosure()) { | 226 if (closure.IsClosure()) { |
| 215 Function& func = Function::Handle(); | 227 Function& func = Function::Handle(); |
| 216 func = Closure::function(closure); | 228 func = Closure::function(closure); |
| 217 if (func.IsImplicitClosureFunction() && func.is_static()) { | 229 if (func.IsImplicitClosureFunction() && func.is_static()) { |
| 218 #if defined(DEBUG) | 230 #if defined(DEBUG) |
| 219 Context& ctx = Context::Handle(); | 231 Context& ctx = Context::Handle(); |
| 220 ctx = Closure::context(closure); | 232 ctx = Closure::context(closure); |
| 221 ASSERT(ctx.num_variables() == 0); | 233 ASSERT(ctx.num_variables() == 0); |
| 222 #endif | 234 #endif |
| 223 // Get the parent function so that we get the right function name. | 235 // Get the parent function so that we get the right function name. |
| 224 func = func.parent_function(); | 236 func = func.parent_function(); |
| 225 | 237 |
| 238 // Get the script URI so that we know what script to load. |
| 239 const Library& root_lib = Library::Handle(zone, |
| 240 isolate->object_store()->root_library()); |
| 241 const String& script_uri = String::Handle(zone, root_lib.url()); |
| 242 |
| 243 const char* utf8_package_root = |
| 244 packageRoot.IsNull() ? NULL : String2UTF8(packageRoot); |
| 245 const char* utf8_package_config = |
| 246 packageConfig.IsNull() ? NULL : String2UTF8(packageConfig); |
| 247 |
| 226 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); | 248 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); |
| 227 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); | 249 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); |
| 228 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); | 250 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); |
| 229 | 251 |
| 230 IsolateSpawnState* state = | 252 IsolateSpawnState* state = |
| 231 new IsolateSpawnState(port.Id(), | 253 new IsolateSpawnState(port.Id(), |
| 232 isolate->origin_id(), | 254 isolate->origin_id(), |
| 233 isolate->init_callback_data(), | 255 isolate->init_callback_data(), |
| 256 String2UTF8(script_uri), |
| 234 func, | 257 func, |
| 235 message, | 258 message, |
| 236 isolate->spawn_count_monitor(), | 259 isolate->spawn_count_monitor(), |
| 237 isolate->spawn_count(), | 260 isolate->spawn_count(), |
| 261 utf8_package_root, |
| 262 utf8_package_config, |
| 238 paused.value(), | 263 paused.value(), |
| 239 fatal_errors, | 264 fatal_errors, |
| 240 on_exit_port, | 265 on_exit_port, |
| 241 on_error_port); | 266 on_error_port); |
| 242 ThreadPool::Task* spawn_task = new SpawnIsolateTask(state); | 267 ThreadPool::Task* spawn_task = new SpawnIsolateTask(state); |
| 243 | 268 |
| 244 isolate->IncrementSpawnCount(); | 269 isolate->IncrementSpawnCount(); |
| 245 if (FLAG_i_like_slow_isolate_spawn) { | 270 if (FLAG_i_like_slow_isolate_spawn) { |
| 246 // We block the parent isolate while the child isolate loads. | 271 // We block the parent isolate while the child isolate loads. |
| 247 Isolate* saved = Isolate::Current(); | 272 Isolate* saved = Isolate::Current(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 261 return Object::null(); | 286 return Object::null(); |
| 262 } | 287 } |
| 263 } | 288 } |
| 264 const String& msg = String::Handle(String::New( | 289 const String& msg = String::Handle(String::New( |
| 265 "Isolate.spawn expects to be passed a static or top-level function")); | 290 "Isolate.spawn expects to be passed a static or top-level function")); |
| 266 Exceptions::ThrowArgumentError(msg); | 291 Exceptions::ThrowArgumentError(msg); |
| 267 return Object::null(); | 292 return Object::null(); |
| 268 } | 293 } |
| 269 | 294 |
| 270 | 295 |
| 271 static const char* String2UTF8(const String& str) { | |
| 272 intptr_t len = Utf8::Length(str); | |
| 273 char* result = new char[len + 1]; | |
| 274 str.ToUTF8(reinterpret_cast<uint8_t*>(result), len); | |
| 275 result[len] = 0; | |
| 276 | |
| 277 return result; | |
| 278 } | |
| 279 | |
| 280 | |
| 281 static const char* CanonicalizeUri(Thread* thread, | 296 static const char* CanonicalizeUri(Thread* thread, |
| 282 const Library& library, | 297 const Library& library, |
| 283 const String& uri, | 298 const String& uri, |
| 284 char** error) { | 299 char** error) { |
| 285 const char* result = NULL; | 300 const char* result = NULL; |
| 286 Zone* zone = thread->zone(); | 301 Zone* zone = thread->zone(); |
| 287 Isolate* isolate = thread->isolate(); | 302 Isolate* isolate = thread->isolate(); |
| 288 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); | 303 Dart_LibraryTagHandler handler = isolate->library_tag_handler(); |
| 289 if (handler != NULL) { | 304 if (handler != NULL) { |
| 290 Dart_EnterScope(); | 305 Dart_EnterScope(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 338 |
| 324 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); | 339 GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4)); |
| 325 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); | 340 GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5)); |
| 326 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); | 341 GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6)); |
| 327 | 342 |
| 328 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); | 343 GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7)); |
| 329 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); | 344 GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8)); |
| 330 | 345 |
| 331 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); | 346 GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9)); |
| 332 | 347 |
| 333 GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(10)); | 348 GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10)); |
| 334 GET_NATIVE_ARGUMENT(Array, packages, arguments->NativeArgAt(11)); | 349 GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11)); |
| 335 | 350 |
| 336 if (Dart::IsRunningPrecompiledCode()) { | 351 if (Dart::IsRunningPrecompiledCode()) { |
| 337 const Array& args = Array::Handle(Array::New(1)); | 352 const Array& args = Array::Handle(Array::New(1)); |
| 338 args.SetAt(0, String::Handle(String::New( | 353 args.SetAt(0, String::Handle(String::New( |
| 339 "Isolate.spawnUri not supported under precompilation"))); | 354 "Isolate.spawnUri not supported under precompilation"))); |
| 340 Exceptions::ThrowByType(Exceptions::kUnsupported, args); | 355 Exceptions::ThrowByType(Exceptions::kUnsupported, args); |
| 341 UNREACHABLE(); | 356 UNREACHABLE(); |
| 342 } | 357 } |
| 343 | 358 |
| 344 // Canonicalize the uri with respect to the current isolate. | 359 // Canonicalize the uri with respect to the current isolate. |
| 345 const Library& root_lib = | 360 const Library& root_lib = |
| 346 Library::Handle(isolate->object_store()->root_library()); | 361 Library::Handle(isolate->object_store()->root_library()); |
| 347 char* error = NULL; | 362 char* error = NULL; |
| 348 const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error); | 363 const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error); |
| 349 if (canonical_uri == NULL) { | 364 if (canonical_uri == NULL) { |
| 350 const String& msg = String::Handle(String::New(error)); | 365 const String& msg = String::Handle(String::New(error)); |
| 351 ThrowIsolateSpawnException(msg); | 366 ThrowIsolateSpawnException(msg); |
| 352 } | 367 } |
| 353 | 368 |
| 354 const char* utf8_package_root = | 369 const char* utf8_package_root = |
| 355 package_root.IsNull() ? NULL : String2UTF8(package_root); | 370 packageRoot.IsNull() ? NULL : String2UTF8(packageRoot); |
| 356 | 371 const char* utf8_package_config = |
| 357 const char** utf8_package_map = NULL; | 372 packageConfig.IsNull() ? NULL : String2UTF8(packageConfig); |
| 358 if (!packages.IsNull()) { | |
| 359 intptr_t len = packages.Length(); | |
| 360 utf8_package_map = new const char*[len + 1]; | |
| 361 | |
| 362 Object& entry = Object::Handle(); | |
| 363 for (intptr_t i = 0; i < len; i++) { | |
| 364 entry = packages.At(i); | |
| 365 if (!entry.IsString()) { | |
| 366 const String& msg = String::Handle(String::NewFormatted( | |
| 367 "Bad value in package map: %s", entry.ToCString())); | |
| 368 ThrowIsolateSpawnException(msg); | |
| 369 } | |
| 370 utf8_package_map[i] = String2UTF8(String::Cast(entry)); | |
| 371 } | |
| 372 // NULL terminated array. | |
| 373 utf8_package_map[len] = NULL; | |
| 374 } | |
| 375 | 373 |
| 376 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); | 374 bool fatal_errors = fatalErrors.IsNull() ? true : fatalErrors.value(); |
| 377 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); | 375 Dart_Port on_exit_port = onExit.IsNull() ? ILLEGAL_PORT : onExit.Id(); |
| 378 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); | 376 Dart_Port on_error_port = onError.IsNull() ? ILLEGAL_PORT : onError.Id(); |
| 379 | 377 |
| 380 IsolateSpawnState* state = | 378 IsolateSpawnState* state = |
| 381 new IsolateSpawnState( | 379 new IsolateSpawnState( |
| 382 port.Id(), | 380 port.Id(), |
| 383 isolate->init_callback_data(), | 381 isolate->init_callback_data(), |
| 384 canonical_uri, | 382 canonical_uri, |
| 385 utf8_package_root, | 383 utf8_package_root, |
| 386 utf8_package_map, | 384 utf8_package_config, |
| 387 args, | 385 args, |
| 388 message, | 386 message, |
| 389 isolate->spawn_count_monitor(), | 387 isolate->spawn_count_monitor(), |
| 390 isolate->spawn_count(), | 388 isolate->spawn_count(), |
| 391 paused.value(), | 389 paused.value(), |
| 392 fatal_errors, | 390 fatal_errors, |
| 393 on_exit_port, | 391 on_exit_port, |
| 394 on_error_port); | 392 on_error_port); |
| 395 | 393 |
| 396 // If we were passed a value then override the default flags state for | 394 // If we were passed a value then override the default flags state for |
| (...skipping 29 matching lines...) Expand all Loading... |
| 426 const Array& result = Array::Handle(Array::New(3)); | 424 const Array& result = Array::Handle(Array::New(3)); |
| 427 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); | 425 result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port()))); |
| 428 result.SetAt(1, Capability::Handle( | 426 result.SetAt(1, Capability::Handle( |
| 429 Capability::New(isolate->pause_capability()))); | 427 Capability::New(isolate->pause_capability()))); |
| 430 result.SetAt(2, Capability::Handle( | 428 result.SetAt(2, Capability::Handle( |
| 431 Capability::New(isolate->terminate_capability()))); | 429 Capability::New(isolate->terminate_capability()))); |
| 432 return result.raw(); | 430 return result.raw(); |
| 433 } | 431 } |
| 434 | 432 |
| 435 | 433 |
| 434 DEFINE_NATIVE_ENTRY(Isolate_getCurrentRootUriStr, 0) { |
| 435 const Library& root_lib = Library::Handle(zone, |
| 436 isolate->object_store()->root_library()); |
| 437 return root_lib.url(); |
| 438 } |
| 439 |
| 440 |
| 436 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) { | 441 DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) { |
| 437 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); | 442 GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0)); |
| 438 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1)); | 443 GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1)); |
| 439 | 444 |
| 440 // Make sure to route this request to the isolate library OOB mesage handler. | 445 // Make sure to route this request to the isolate library OOB mesage handler. |
| 441 msg.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg))); | 446 msg.SetAt(0, Smi::Handle(Smi::New(Message::kIsolateLibOOBMsg))); |
| 442 | 447 |
| 443 uint8_t* data = NULL; | 448 uint8_t* data = NULL; |
| 444 MessageWriter writer(&data, &allocator, false); | 449 MessageWriter writer(&data, &allocator, false); |
| 445 writer.WriteMessage(msg); | 450 writer.WriteMessage(msg); |
| 446 | 451 |
| 447 PortMap::PostMessage(new Message(port.Id(), | 452 PortMap::PostMessage(new Message(port.Id(), |
| 448 data, writer.BytesWritten(), | 453 data, writer.BytesWritten(), |
| 449 Message::kOOBPriority)); | 454 Message::kOOBPriority)); |
| 450 return Object::null(); | 455 return Object::null(); |
| 451 } | 456 } |
| 452 | 457 |
| 453 } // namespace dart | 458 } // namespace dart |
| OLD | NEW |