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 |