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" |
11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
12 #include "vm/longjump.h" | 12 #include "vm/longjump.h" |
13 #include "vm/message.h" | 13 #include "vm/message_handler.h" |
14 #include "vm/object.h" | 14 #include "vm/object.h" |
15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
16 #include "vm/port.h" | 16 #include "vm/port.h" |
17 #include "vm/resolver.h" | 17 #include "vm/resolver.h" |
18 #include "vm/snapshot.h" | 18 #include "vm/snapshot.h" |
19 #include "vm/thread.h" | 19 #include "vm/thread.h" |
20 | 20 |
21 namespace dart { | 21 namespace dart { |
22 | 22 |
23 class IsolateStartData { | 23 class IsolateStartData { |
24 public: | 24 public: |
25 IsolateStartData(Isolate* isolate, | 25 IsolateStartData(char* library_url, |
26 char* library_url, | |
27 char* class_name, | 26 char* class_name, |
28 intptr_t port_id) | 27 intptr_t port_id) |
29 : isolate_(isolate), | 28 : library_url_(library_url), |
30 library_url_(library_url), | |
31 class_name_(class_name), | 29 class_name_(class_name), |
32 port_id_(port_id) {} | 30 port_id_(port_id) {} |
33 | 31 |
34 Isolate* isolate_; | |
35 char* library_url_; | 32 char* library_url_; |
36 char* class_name_; | 33 char* class_name_; |
37 intptr_t port_id_; | 34 intptr_t port_id_; |
38 }; | 35 }; |
39 | 36 |
40 | 37 |
41 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 38 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
42 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 39 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
43 return reinterpret_cast<uint8_t*>(new_ptr); | 40 return reinterpret_cast<uint8_t*>(new_ptr); |
44 } | 41 } |
45 | 42 |
46 | 43 |
47 static uint8_t* SerializeObject(const Instance& obj) { | 44 static uint8_t* SerializeObject(const Instance& obj) { |
48 uint8_t* result = NULL; | 45 uint8_t* result = NULL; |
49 SnapshotWriter writer(Snapshot::kMessage, &result, &allocator); | 46 SnapshotWriter writer(Snapshot::kMessage, &result, &allocator); |
50 writer.WriteObject(obj.raw()); | 47 writer.WriteObject(obj.raw()); |
51 writer.FinalizeBuffer(); | 48 writer.FinalizeBuffer(); |
52 return result; | 49 return result; |
53 } | 50 } |
54 | 51 |
55 | 52 |
56 // TODO(turnidge): Taking down the whole vm when an isolate fails is | 53 static void StoreError(Isolate* isolate, const Object& obj) { |
57 // bad. Change this. | |
58 static void ProcessError(const Object& obj) { | |
59 ASSERT(obj.IsError()); | 54 ASSERT(obj.IsError()); |
60 Error& error = Error::Handle(); | 55 Error& error = Error::Handle(); |
61 error ^= obj.raw(); | 56 error ^= obj.raw(); |
62 OS::PrintErr("%s\n", error.ToErrorCString()); | 57 isolate->object_store()->set_sticky_error(error); |
63 exit(255); | |
64 } | 58 } |
65 | 59 |
66 | 60 |
67 static void ThrowErrorException(Exceptions::ExceptionType type, | 61 static void ThrowErrorException(Exceptions::ExceptionType type, |
68 const char* error_msg, | 62 const char* error_msg, |
69 const char* library_url, | 63 const char* library_url, |
70 const char* class_name) { | 64 const char* class_name) { |
71 String& str = String::Handle(); | 65 String& str = String::Handle(); |
72 String& name = String::Handle(); | 66 String& name = String::Handle(); |
73 str ^= String::New(error_msg); | 67 str ^= String::New(error_msg); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 arguments.Add(&Integer::Handle(Integer::New(port_id))); | 100 arguments.Add(&Integer::Handle(Integer::New(port_id))); |
107 const Object& result = Object::Handle( | 101 const Object& result = Object::Handle( |
108 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); | 102 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
109 if (!result.IsError()) { | 103 if (!result.IsError()) { |
110 PortMap::SetLive(port_id); | 104 PortMap::SetLive(port_id); |
111 } | 105 } |
112 return result.raw(); | 106 return result.raw(); |
113 } | 107 } |
114 | 108 |
115 | 109 |
116 static void RunIsolate(uword parameter) { | 110 static bool RunIsolate(uword parameter) { |
117 IsolateStartData* data = reinterpret_cast<IsolateStartData*>(parameter); | 111 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
118 Isolate* isolate = data->isolate_; | 112 IsolateStartData* data = |
113 reinterpret_cast<IsolateStartData*>(isolate->spawn_data()); | |
114 isolate->set_spawn_data(NULL); | |
119 char* library_url = data->library_url_; | 115 char* library_url = data->library_url_; |
120 char* class_name = data->class_name_; | 116 char* class_name = data->class_name_; |
121 intptr_t port_id = data->port_id_; | 117 intptr_t port_id = data->port_id_; |
siva
2012/04/18 22:05:00
When is data deleted in the new scheme?
turnidge
2012/04/19 19:46:55
That was missing. Added.
| |
122 delete data; | |
123 | 118 |
124 Isolate::SetCurrent(isolate); | 119 { |
125 // Intialize stack limit in case we are running isolate in a | 120 StartIsolateScope start_scope(isolate); |
126 // different thread than in which it was initialized. | |
127 isolate->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&isolate)); | |
128 LongJump* base = isolate->long_jump_base(); | |
129 LongJump jump; | |
130 isolate->set_long_jump_base(&jump); | |
131 if (setjmp(*jump.Set()) == 0) { | |
132 Zone zone(isolate); | 121 Zone zone(isolate); |
133 HandleScope handle_scope(isolate); | 122 HandleScope handle_scope(isolate); |
134 ASSERT(ClassFinalizer::FinalizePendingClasses()); | 123 ASSERT(ClassFinalizer::FinalizePendingClasses()); |
135 // Lookup the target class by name, create an instance and call the run | 124 // Lookup the target class by name, create an instance and call the run |
136 // method. | 125 // method. |
137 const String& lib_name = String::Handle(String::NewSymbol(library_url)); | 126 const String& lib_name = String::Handle(String::NewSymbol(library_url)); |
127 free(library_url); | |
138 const Library& lib = Library::Handle(Library::LookupLibrary(lib_name)); | 128 const Library& lib = Library::Handle(Library::LookupLibrary(lib_name)); |
139 ASSERT(!lib.IsNull()); | 129 ASSERT(!lib.IsNull()); |
140 const String& cls_name = String::Handle(String::NewSymbol(class_name)); | 130 const String& cls_name = String::Handle(String::NewSymbol(class_name)); |
131 free(class_name); | |
141 const Class& target_class = Class::Handle(lib.LookupClass(cls_name)); | 132 const Class& target_class = Class::Handle(lib.LookupClass(cls_name)); |
142 // TODO(iposva): Deserialize or call the constructor after allocating. | 133 // TODO(iposva): Deserialize or call the constructor after allocating. |
143 // For now, we only support a non-parameterized or raw target class. | 134 // For now, we only support a non-parameterized or raw target class. |
144 const Instance& target = Instance::Handle(Instance::New(target_class)); | 135 const Instance& target = Instance::Handle(Instance::New(target_class)); |
145 Object& result = Object::Handle(); | 136 Object& result = Object::Handle(); |
146 | 137 |
147 // Invoke the default constructor. | 138 // Invoke the default constructor. |
148 const String& period = String::Handle(String::New(".")); | 139 const String& period = String::Handle(String::New(".")); |
149 String& constructor_name = String::Handle(String::Concat(cls_name, period)); | 140 String& constructor_name = String::Handle(String::Concat(cls_name, period)); |
150 const Function& default_constructor = | 141 const Function& default_constructor = |
151 Function::Handle(target_class.LookupConstructor(constructor_name)); | 142 Function::Handle(target_class.LookupConstructor(constructor_name)); |
152 if (!default_constructor.IsNull()) { | 143 if (!default_constructor.IsNull()) { |
153 GrowableArray<const Object*> arguments(1); | 144 GrowableArray<const Object*> arguments(1); |
154 arguments.Add(&target); | 145 arguments.Add(&target); |
155 arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 146 arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
156 const Array& kNoArgumentNames = Array::Handle(); | 147 const Array& kNoArgumentNames = Array::Handle(); |
157 result = DartEntry::InvokeStatic(default_constructor, | 148 result = DartEntry::InvokeStatic(default_constructor, |
158 arguments, | 149 arguments, |
159 kNoArgumentNames); | 150 kNoArgumentNames); |
160 if (result.IsError()) { | 151 if (result.IsError()) { |
161 ProcessError(result); | 152 StoreError(isolate, result); |
153 return false; | |
162 } | 154 } |
163 ASSERT(result.IsNull()); | 155 ASSERT(result.IsNull()); |
164 } | 156 } |
165 | 157 |
166 // Invoke the "_run" method. | 158 // Invoke the "_run" method. |
167 const Function& target_function = Function::Handle(Resolver::ResolveDynamic( | 159 const Function& target_function = Function::Handle(Resolver::ResolveDynamic( |
168 target, String::Handle(String::NewSymbol("_run")), 2, 0)); | 160 target, String::Handle(String::NewSymbol("_run")), 2, 0)); |
169 // TODO(iposva): Proper error checking here. | 161 // TODO(iposva): Proper error checking here. |
170 ASSERT(!target_function.IsNull()); | 162 ASSERT(!target_function.IsNull()); |
171 // TODO(iposva): Allocate the proper port number here. | 163 // TODO(iposva): Allocate the proper port number here. |
172 const Object& local_port = Object::Handle(ReceivePortCreate(port_id)); | 164 const Object& local_port = Object::Handle(ReceivePortCreate(port_id)); |
173 if (local_port.IsError()) { | 165 if (local_port.IsError()) { |
174 ProcessError(local_port); | 166 StoreError(isolate, local_port); |
167 return false; | |
175 } | 168 } |
176 GrowableArray<const Object*> arguments(1); | 169 GrowableArray<const Object*> arguments(1); |
177 arguments.Add(&local_port); | 170 arguments.Add(&local_port); |
178 const Array& kNoArgumentNames = Array::Handle(); | 171 const Array& kNoArgumentNames = Array::Handle(); |
179 result = DartEntry::InvokeDynamic(target, | 172 result = DartEntry::InvokeDynamic(target, |
180 target_function, | 173 target_function, |
181 arguments, | 174 arguments, |
182 kNoArgumentNames); | 175 kNoArgumentNames); |
183 if (result.IsError()) { | 176 if (result.IsError()) { |
184 ProcessError(result); | 177 StoreError(isolate, result); |
178 return false; | |
185 } | 179 } |
186 ASSERT(result.IsNull()); | 180 ASSERT(result.IsNull()); |
187 free(class_name); | 181 } |
188 free(library_url); | 182 return true; |
189 result = isolate->StandardRunLoop(); | 183 } |
190 if (result.IsError()) { | |
191 ProcessError(result); | |
192 } | |
193 ASSERT(result.IsNull()); | |
194 | 184 |
195 } else { | 185 |
186 static void ShutdownIsolate(uword parameter) { | |
187 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | |
188 SwitchIsolateScope switch_scope(isolate); | |
189 { | |
196 Zone zone(isolate); | 190 Zone zone(isolate); |
197 HandleScope handle_scope(isolate); | 191 HandleScope handle_scope(isolate); |
198 const Error& error = Error::Handle( | 192 Error& error = Error::Handle(); |
199 Isolate::Current()->object_store()->sticky_error()); | 193 error = isolate->object_store()->sticky_error(); |
200 const char* errmsg = error.ToErrorCString(); | 194 if (!error.IsNull()) { |
201 OS::PrintErr("%s\n", errmsg); | 195 OS::PrintErr("%s\n", error.ToErrorCString()); |
202 exit(255); | 196 exit(255); |
197 } | |
203 } | 198 } |
204 isolate->set_long_jump_base(base); | |
205 Dart::ShutdownIsolate(); | 199 Dart::ShutdownIsolate(); |
206 } | 200 } |
207 | 201 |
208 | 202 |
209 static bool CheckArguments(const char* library_url, const char* class_name) { | 203 static bool CheckArguments(const char* library_url, const char* class_name) { |
210 Isolate* isolate = Isolate::Current(); | 204 Isolate* isolate = Isolate::Current(); |
211 Zone zone(isolate); | 205 Zone zone(isolate); |
212 HandleScope handle_scope(isolate); | 206 HandleScope handle_scope(isolate); |
213 String& name = String::Handle(); | 207 String& name = String::Handle(); |
214 if (!ClassFinalizer::FinalizePendingClasses()) { | 208 if (!ClassFinalizer::FinalizePendingClasses()) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 const char* isolate_name = BuildIsolateName(library_url, class_name, "main"); | 279 const char* isolate_name = BuildIsolateName(library_url, class_name, "main"); |
286 if (callback == NULL) { | 280 if (callback == NULL) { |
287 error = strdup("Null callback specified for isolate creation\n"); | 281 error = strdup("Null callback specified for isolate creation\n"); |
288 } else if (callback(isolate_name, callback_data, &error)) { | 282 } else if (callback(isolate_name, callback_data, &error)) { |
289 spawned_isolate = Isolate::Current(); | 283 spawned_isolate = Isolate::Current(); |
290 ASSERT(spawned_isolate != NULL); | 284 ASSERT(spawned_isolate != NULL); |
291 // Check arguments to see if the specified library and classes are | 285 // Check arguments to see if the specified library and classes are |
292 // loaded, this check will throw an exception if they are not loaded. | 286 // loaded, this check will throw an exception if they are not loaded. |
293 if (init_successful && CheckArguments(library_url, class_name)) { | 287 if (init_successful && CheckArguments(library_url, class_name)) { |
294 port_id = spawned_isolate->main_port(); | 288 port_id = spawned_isolate->main_port(); |
295 uword data = reinterpret_cast<uword>( | 289 spawned_isolate->set_spawn_data( |
296 new IsolateStartData(spawned_isolate, | 290 reinterpret_cast<uword>( |
297 strdup(library_url), | 291 new IsolateStartData(strdup(library_url), |
298 strdup(class_name), | 292 strdup(class_name), |
299 port_id)); | 293 port_id))); |
300 int result = Thread::Start(RunIsolate, data); | 294 Isolate::SetCurrent(NULL); |
301 if (result != 0) { | 295 spawned_isolate->message_handler()->Run( |
302 FATAL1("Failed to start isolate thread %d", result); | 296 Dart::thread_pool(), RunIsolate, ShutdownIsolate, |
303 } | 297 reinterpret_cast<uword>(spawned_isolate)); |
304 } else { | 298 } else { |
305 // Error spawning the isolate, maybe due to initialization errors or | 299 // Error spawning the isolate, maybe due to initialization errors or |
306 // errors while loading the application into spawned isolate, shut | 300 // errors while loading the application into spawned isolate, shut |
307 // it down and report error. | 301 // it down and report error. |
308 // Make sure to grab the error message out of the isolate before it has | 302 // Make sure to grab the error message out of the isolate before it has |
309 // been shutdown and to allocate it in the preserved isolates zone. | 303 // been shutdown and to allocate it in the preserved isolates zone. |
310 { | 304 { |
311 Zone zone(spawned_isolate); | 305 Zone zone(spawned_isolate); |
312 HandleScope scope(spawned_isolate); | 306 HandleScope scope(spawned_isolate); |
313 const Error& err_obj = Error::Handle( | 307 const Error& err_obj = Error::Handle( |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 String::Handle(String::NewSymbol(function_name())); | 412 String::Handle(String::NewSymbol(function_name())); |
419 | 413 |
420 const Library& lib = Library::Handle(Library::LookupLibrary(lib_url)); | 414 const Library& lib = Library::Handle(Library::LookupLibrary(lib_url)); |
421 if (lib.IsNull() || lib.IsError()) { | 415 if (lib.IsNull() || lib.IsError()) { |
422 return Function::null(); | 416 return Function::null(); |
423 } | 417 } |
424 return lib.LookupLocalFunction(func_name); | 418 return lib.LookupLocalFunction(func_name); |
425 } | 419 } |
426 | 420 |
427 void Cleanup() { | 421 void Cleanup() { |
428 Isolate* saved = Isolate::Current(); | 422 SwitchIsolateScope switch_scope(isolate()); |
429 Isolate::SetCurrent(isolate()); | |
430 Dart::ShutdownIsolate(); | 423 Dart::ShutdownIsolate(); |
431 Isolate::SetCurrent(saved); | |
432 } | 424 } |
433 | 425 |
434 private: | 426 private: |
435 Isolate* isolate_; | 427 Isolate* isolate_; |
436 char* library_url_; | 428 char* library_url_; |
437 char* function_name_; | 429 char* function_name_; |
438 }; | 430 }; |
439 | 431 |
440 | 432 |
441 static bool CreateIsolate(SpawnState* state, char** error) { | 433 static bool CreateIsolate(SpawnState* state, char** error) { |
(...skipping 30 matching lines...) Expand all Loading... | |
472 } | 464 } |
473 } | 465 } |
474 if (!retval) { | 466 if (!retval) { |
475 Dart::ShutdownIsolate(); | 467 Dart::ShutdownIsolate(); |
476 } | 468 } |
477 Isolate::SetCurrent(parent_isolate); | 469 Isolate::SetCurrent(parent_isolate); |
478 return retval; | 470 return retval; |
479 } | 471 } |
480 | 472 |
481 | 473 |
482 static void RunIsolate2(uword parameter) { | 474 static bool RunIsolate2(uword parameter) { |
483 SpawnState* state = reinterpret_cast<SpawnState*>(parameter); | 475 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); |
484 Isolate* isolate = state->isolate(); | 476 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data()); |
485 | 477 isolate->set_spawn_data(NULL); |
486 Isolate::SetCurrent(isolate); | |
487 // Intialize stack limit in case we are running isolate in a | |
488 // different thread than in which it was initialized. | |
489 isolate->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&isolate)); | |
490 | |
491 { | 478 { |
479 StartIsolateScope start_scope(isolate); | |
492 Zone zone(isolate); | 480 Zone zone(isolate); |
493 HandleScope handle_scope(isolate); | 481 HandleScope handle_scope(isolate); |
494 ASSERT(ClassFinalizer::FinalizePendingClasses()); | 482 ASSERT(ClassFinalizer::FinalizePendingClasses()); |
495 Object& result = Object::Handle(); | 483 Object& result = Object::Handle(); |
496 | 484 |
497 const Function& func = Function::Handle(state->ResolveFunction()); | 485 const Function& func = Function::Handle(state->ResolveFunction()); |
498 delete state; | 486 delete state; |
499 state = NULL; | 487 state = NULL; |
500 ASSERT(!func.IsNull()); | 488 ASSERT(!func.IsNull()); |
501 | 489 |
502 GrowableArray<const Object*> args(0); | 490 GrowableArray<const Object*> args(0); |
503 const Array& kNoArgNames = Array::Handle(); | 491 const Array& kNoArgNames = Array::Handle(); |
504 result = DartEntry::InvokeStatic(func, args, kNoArgNames); | 492 result = DartEntry::InvokeStatic(func, args, kNoArgNames); |
505 if (result.IsError()) { | 493 if (result.IsError()) { |
506 ProcessError(result); | 494 StoreError(isolate, result); |
495 return false; | |
507 } | 496 } |
508 | |
509 result = isolate->StandardRunLoop(); | |
510 if (result.IsError()) { | |
511 ProcessError(result); | |
512 } | |
513 ASSERT(result.IsNull()); | |
514 } | 497 } |
515 Dart::ShutdownIsolate(); | 498 return true; |
516 } | 499 } |
517 | 500 |
518 | 501 |
519 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { | 502 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) { |
520 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0)); | 503 GET_NATIVE_ARGUMENT(Closure, closure, arguments->At(0)); |
521 const Function& func = Function::Handle(closure.function()); | 504 const Function& func = Function::Handle(closure.function()); |
522 const Class& cls = Class::Handle(func.owner()); | 505 const Class& cls = Class::Handle(func.owner()); |
523 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { | 506 if (!func.IsClosureFunction() || !func.is_static() || !cls.IsTopLevel()) { |
524 const String& msg = String::Handle(String::New( | 507 const String& msg = String::Handle(String::New( |
525 "spawnFunction expects to be passed a closure to a top-level static " | 508 "spawnFunction expects to be passed a closure to a top-level static " |
(...skipping 18 matching lines...) Expand all Loading... | |
544 // Try to create a SendPort for the new isolate. | 527 // Try to create a SendPort for the new isolate. |
545 const Object& port = Object::Handle( | 528 const Object& port = Object::Handle( |
546 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); | 529 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); |
547 if (port.IsError()) { | 530 if (port.IsError()) { |
548 state->Cleanup(); | 531 state->Cleanup(); |
549 delete state; | 532 delete state; |
550 Exceptions::PropagateError(port); | 533 Exceptions::PropagateError(port); |
551 } | 534 } |
552 | 535 |
553 // Start the new isolate. | 536 // Start the new isolate. |
554 int result = Thread::Start(RunIsolate2, reinterpret_cast<uword>(state)); | 537 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); |
555 if (result != 0) { | 538 state->isolate()->message_handler()->Run( |
556 const String& msg = String::Handle(String::NewFormatted( | 539 Dart::thread_pool(), RunIsolate2, ShutdownIsolate, |
557 "Failed to start thread for isolate '%s'. Error code '%d'.", | 540 reinterpret_cast<uword>(state->isolate())); |
558 state->isolate()->name(), result)); | |
559 state->Cleanup(); | |
560 delete state; | |
561 ThrowIsolateSpawnException(msg); | |
562 } | |
563 | 541 |
564 arguments->SetReturn(port); | 542 arguments->SetReturn(port); |
565 } | 543 } |
566 | 544 |
567 | 545 |
568 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { | 546 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { |
569 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); | 547 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); |
570 if (port.IsError()) { | 548 if (port.IsError()) { |
571 Exceptions::PropagateError(port); | 549 Exceptions::PropagateError(port); |
572 } | 550 } |
573 arguments->SetReturn(port); | 551 arguments->SetReturn(port); |
574 } | 552 } |
575 | 553 |
576 } // namespace dart | 554 } // namespace dart |
OLD | NEW |