OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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_api.h" | 5 #include "include/dart_api.h" |
6 | 6 |
7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 static void SetupErrorResult(Dart_Handle* handle) { | 78 static void SetupErrorResult(Dart_Handle* handle) { |
79 // Make a copy of the error message as the original message string | 79 // Make a copy of the error message as the original message string |
80 // may get deallocated when we return back from the Dart API call. | 80 // may get deallocated when we return back from the Dart API call. |
81 const String& error = String::Handle( | 81 const String& error = String::Handle( |
82 Isolate::Current()->object_store()->sticky_error()); | 82 Isolate::Current()->object_store()->sticky_error()); |
83 const Object& obj = Object::Handle(ApiError::New(error)); | 83 const Object& obj = Object::Handle(ApiError::New(error)); |
84 *handle = Api::NewLocalHandle(obj); | 84 *handle = Api::NewLocalHandle(obj); |
85 } | 85 } |
86 | 86 |
87 | 87 |
| 88 // NOTE: Need to pass 'result' as a parameter here in order to avoid |
| 89 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' |
| 90 // which shows up because of the use of setjmp. |
| 91 static void InvokeStatic(Isolate* isolate, |
| 92 const Function& function, |
| 93 GrowableArray<const Object*>& args, |
| 94 Dart_Handle* result) { |
| 95 ASSERT(isolate != NULL); |
| 96 LongJump* base = isolate->long_jump_base(); |
| 97 LongJump jump; |
| 98 isolate->set_long_jump_base(&jump); |
| 99 if (setjmp(*jump.Set()) == 0) { |
| 100 const Array& kNoArgumentNames = Array::Handle(); |
| 101 const Instance& retval = Instance::Handle( |
| 102 DartEntry::InvokeStatic(function, args, kNoArgumentNames)); |
| 103 if (retval.IsUnhandledException()) { |
| 104 *result = Api::ErrorFromException(retval); |
| 105 } else { |
| 106 *result = Api::NewLocalHandle(retval); |
| 107 } |
| 108 } else { |
| 109 SetupErrorResult(result); |
| 110 } |
| 111 isolate->set_long_jump_base(base); |
| 112 } |
| 113 |
| 114 |
| 115 // NOTE: Need to pass 'result' as a parameter here in order to avoid |
| 116 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' |
| 117 // which shows up because of the use of setjmp. |
| 118 static void InvokeDynamic(Isolate* isolate, |
| 119 const Instance& receiver, |
| 120 const Function& function, |
| 121 GrowableArray<const Object*>& args, |
| 122 Dart_Handle* result) { |
| 123 ASSERT(isolate != NULL); |
| 124 LongJump* base = isolate->long_jump_base(); |
| 125 LongJump jump; |
| 126 isolate->set_long_jump_base(&jump); |
| 127 if (setjmp(*jump.Set()) == 0) { |
| 128 const Array& kNoArgumentNames = Array::Handle(); |
| 129 const Instance& retval = Instance::Handle( |
| 130 DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames)); |
| 131 if (retval.IsUnhandledException()) { |
| 132 *result = Api::ErrorFromException(retval); |
| 133 } else { |
| 134 *result = Api::NewLocalHandle(retval); |
| 135 } |
| 136 } else { |
| 137 SetupErrorResult(result); |
| 138 } |
| 139 isolate->set_long_jump_base(base); |
| 140 } |
| 141 |
| 142 |
88 Dart_Handle Api::NewLocalHandle(const Object& object) { | 143 Dart_Handle Api::NewLocalHandle(const Object& object) { |
89 Isolate* isolate = Isolate::Current(); | 144 Isolate* isolate = Isolate::Current(); |
90 ASSERT(isolate != NULL); | 145 ASSERT(isolate != NULL); |
91 ApiState* state = isolate->api_state(); | 146 ApiState* state = isolate->api_state(); |
92 ASSERT(state != NULL); | 147 ASSERT(state != NULL); |
93 ApiLocalScope* scope = state->top_scope(); | 148 ApiLocalScope* scope = state->top_scope(); |
94 ASSERT(scope != NULL); | 149 ASSERT(scope != NULL); |
95 LocalHandles* local_handles = scope->local_handles(); | 150 LocalHandles* local_handles = scope->local_handles(); |
96 ASSERT(local_handles != NULL); | 151 ASSERT(local_handles != NULL); |
97 LocalHandle* ref = local_handles->AllocateHandle(); | 152 LocalHandle* ref = local_handles->AllocateHandle(); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 return Api::NewLocalHandle(stacktrace); | 407 return Api::NewLocalHandle(stacktrace); |
353 } else { | 408 } else { |
354 return Api::Error("This error is not an unhandled exception error."); | 409 return Api::Error("This error is not an unhandled exception error."); |
355 } | 410 } |
356 } else { | 411 } else { |
357 return Api::Error("Can only get stacktraces from error handles."); | 412 return Api::Error("Can only get stacktraces from error handles."); |
358 } | 413 } |
359 } | 414 } |
360 | 415 |
361 | 416 |
362 // TODO(turnidge): This clonse Api::Error. I need to use va_copy to | 417 // TODO(turnidge): This clones Api::Error. I need to use va_copy to |
363 // fix this but not sure if it available on all of our builds. | 418 // fix this but not sure if it available on all of our builds. |
364 DART_EXPORT Dart_Handle Dart_Error(const char* format, ...) { | 419 DART_EXPORT Dart_Handle Dart_Error(const char* format, ...) { |
365 DARTSCOPE(Isolate::Current()); | 420 DARTSCOPE(Isolate::Current()); |
366 | 421 |
367 va_list args; | 422 va_list args; |
368 va_start(args, format); | 423 va_start(args, format); |
369 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 424 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
370 va_end(args); | 425 va_end(args); |
371 | 426 |
372 char* buffer = reinterpret_cast<char*>(zone.Allocate(len + 1)); | 427 char* buffer = reinterpret_cast<char*>(zone.Allocate(len + 1)); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 | 640 |
586 // Read object back from the snapshot. | 641 // Read object back from the snapshot. |
587 Isolate* isolate = Isolate::Current(); | 642 Isolate* isolate = Isolate::Current(); |
588 SnapshotReader reader(snapshot, isolate->heap(), isolate->object_store()); | 643 SnapshotReader reader(snapshot, isolate->heap(), isolate->object_store()); |
589 Instance& instance = Instance::Handle(); | 644 Instance& instance = Instance::Handle(); |
590 instance ^= reader.ReadObject(); | 645 instance ^= reader.ReadObject(); |
591 return instance.raw(); | 646 return instance.raw(); |
592 } | 647 } |
593 | 648 |
594 | 649 |
595 DART_EXPORT Dart_Handle Dart_HandleMessage(Dart_Port dest_port, | 650 DART_EXPORT Dart_Handle Dart_HandleMessage(Dart_Port dest_port_id, |
596 Dart_Port reply_port, | 651 Dart_Port reply_port_id, |
597 Dart_Message dart_message) { | 652 Dart_Message dart_message) { |
598 DARTSCOPE(Isolate::Current()); | 653 DARTSCOPE(Isolate::Current()); |
599 | 654 |
600 const Instance& msg = Instance::Handle(DeserializeMessage(dart_message)); | 655 const Instance& msg = Instance::Handle(DeserializeMessage(dart_message)); |
601 const String& class_name = | 656 const String& class_name = |
602 String::Handle(String::NewSymbol("ReceivePortImpl")); | 657 String::Handle(String::NewSymbol("ReceivePortImpl")); |
603 const String& function_name = | 658 const String& function_name = |
604 String::Handle(String::NewSymbol("handleMessage_")); | 659 String::Handle(String::NewSymbol("_handleMessage")); |
605 const int kNumArguments = 3; | 660 const int kNumArguments = 3; |
606 const Array& kNoArgumentNames = Array::Handle(); | 661 const Array& kNoArgumentNames = Array::Handle(); |
607 const Function& function = Function::Handle( | 662 const Function& function = Function::Handle( |
608 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), | 663 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), |
609 class_name, | 664 class_name, |
610 function_name, | 665 function_name, |
611 kNumArguments, | 666 kNumArguments, |
612 kNoArgumentNames, | 667 kNoArgumentNames, |
613 Resolver::kIsQualified)); | 668 Resolver::kIsQualified)); |
614 GrowableArray<const Object*> arguments(kNumArguments); | 669 GrowableArray<const Object*> arguments(kNumArguments); |
615 arguments.Add(&Integer::Handle(Integer::New(dest_port))); | 670 arguments.Add(&Integer::Handle(Integer::New(dest_port_id))); |
616 arguments.Add(&Integer::Handle(Integer::New(reply_port))); | 671 arguments.Add(&Integer::Handle(Integer::New(reply_port_id))); |
617 arguments.Add(&msg); | 672 arguments.Add(&msg); |
| 673 // TODO(turnidge): This call should be wrapped in a longjmp |
618 const Object& result = Object::Handle( | 674 const Object& result = Object::Handle( |
619 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); | 675 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
620 if (result.IsUnhandledException()) { | 676 if (result.IsUnhandledException()) { |
621 return Api::ErrorFromException(result); | 677 return Api::ErrorFromException(result); |
622 } | 678 } |
623 ASSERT(result.IsNull()); | 679 ASSERT(result.IsNull()); |
624 return Api::Success(); | 680 return Api::Success(); |
625 } | 681 } |
626 | 682 |
627 | 683 |
628 DART_EXPORT Dart_Handle Dart_RunLoop() { | 684 DART_EXPORT Dart_Handle Dart_RunLoop() { |
629 Isolate* isolate = Isolate::Current(); | 685 Isolate* isolate = Isolate::Current(); |
630 DARTSCOPE(isolate); | 686 DARTSCOPE(isolate); |
631 | 687 |
632 LongJump* base = isolate->long_jump_base(); | 688 LongJump* base = isolate->long_jump_base(); |
633 LongJump jump; | 689 LongJump jump; |
634 Dart_Handle result; | 690 Dart_Handle result; |
635 isolate->set_long_jump_base(&jump); | 691 isolate->set_long_jump_base(&jump); |
636 if (setjmp(*jump.Set()) == 0) { | 692 if (setjmp(*jump.Set()) == 0) { |
637 isolate->StandardRunLoop(); | 693 isolate->StandardRunLoop(); |
638 result = Api::Success(); | 694 result = Api::Success(); |
639 } else { | 695 } else { |
640 SetupErrorResult(&result); | 696 SetupErrorResult(&result); |
641 } | 697 } |
642 isolate->set_long_jump_base(base); | 698 isolate->set_long_jump_base(base); |
643 return result; | 699 return result; |
644 } | 700 } |
645 | 701 |
646 | 702 |
| 703 DART_EXPORT bool Dart_HasLivePorts() { |
| 704 Isolate* isolate = Isolate::Current(); |
| 705 ASSERT(isolate); |
| 706 return isolate->live_ports() > 0; |
| 707 } |
| 708 |
| 709 |
647 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 710 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
648 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 711 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
649 return reinterpret_cast<uint8_t*>(new_ptr); | 712 return reinterpret_cast<uint8_t*>(new_ptr); |
650 } | 713 } |
651 | 714 |
652 | 715 |
653 DART_EXPORT bool Dart_PostIntArray(Dart_Port port, | 716 DART_EXPORT bool Dart_PostIntArray(Dart_Port port_id, |
654 intptr_t len, | 717 intptr_t len, |
655 intptr_t* data) { | 718 intptr_t* data) { |
656 uint8_t* buffer = NULL; | 719 uint8_t* buffer = NULL; |
657 MessageWriter writer(&buffer, &allocator); | 720 MessageWriter writer(&buffer, &allocator); |
658 | 721 |
659 writer.WriteMessage(len, data); | 722 writer.WriteMessage(len, data); |
660 | 723 |
661 // Post the message at the given port. | 724 // Post the message at the given port. |
662 return PortMap::PostMessage(port, kNoReplyPort, buffer); | 725 return PortMap::PostMessage(port_id, kNoReplyPort, buffer); |
663 } | 726 } |
664 | 727 |
665 | 728 |
666 DART_EXPORT bool Dart_Post(Dart_Port port, Dart_Handle handle) { | 729 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) { |
667 DARTSCOPE(Isolate::Current()); | 730 DARTSCOPE(Isolate::Current()); |
668 const Object& object = Object::Handle(Api::UnwrapHandle(handle)); | 731 const Object& object = Object::Handle(Api::UnwrapHandle(handle)); |
669 uint8_t* data = NULL; | 732 uint8_t* data = NULL; |
670 SnapshotWriter writer(false, &data, &allocator); | 733 SnapshotWriter writer(false, &data, &allocator); |
671 writer.WriteObject(object.raw()); | 734 writer.WriteObject(object.raw()); |
672 writer.FinalizeBuffer(); | 735 writer.FinalizeBuffer(); |
673 return PortMap::PostMessage(port, kNoReplyPort, data); | 736 return PortMap::PostMessage(port_id, kNoReplyPort, data); |
674 } | 737 } |
675 | 738 |
676 | 739 |
| 740 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) { |
| 741 Isolate* isolate = Isolate::Current(); |
| 742 DARTSCOPE(isolate); |
| 743 const String& class_name = String::Handle(String::NewSymbol("SendPortImpl")); |
| 744 const String& function_name = String::Handle(String::NewSymbol("_create")); |
| 745 const int kNumArguments = 1; |
| 746 const Array& kNoArgumentNames = Array::Handle(); |
| 747 // TODO(turnidge): Consider adding a helper function to make |
| 748 // function resolution by class name and function name more concise. |
| 749 const Function& function = Function::Handle( |
| 750 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), |
| 751 class_name, |
| 752 function_name, |
| 753 kNumArguments, |
| 754 kNoArgumentNames, |
| 755 Resolver::kIsQualified)); |
| 756 GrowableArray<const Object*> arguments(kNumArguments); |
| 757 arguments.Add(&Integer::Handle(Integer::New(port_id))); |
| 758 Dart_Handle result; |
| 759 InvokeStatic(isolate, function, arguments, &result); |
| 760 return result; |
| 761 } |
| 762 |
| 763 |
| 764 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) { |
| 765 Isolate* isolate = Isolate::Current(); |
| 766 DARTSCOPE(isolate); |
| 767 const String& class_name = |
| 768 String::Handle(String::NewSymbol("ReceivePortImpl")); |
| 769 const String& function_name = |
| 770 String::Handle(String::NewSymbol("_get_or_create")); |
| 771 const int kNumArguments = 1; |
| 772 const Array& kNoArgumentNames = Array::Handle(); |
| 773 const Function& function = Function::Handle( |
| 774 Resolver::ResolveStatic(Library::Handle(Library::CoreLibrary()), |
| 775 class_name, |
| 776 function_name, |
| 777 kNumArguments, |
| 778 kNoArgumentNames, |
| 779 Resolver::kIsQualified)); |
| 780 GrowableArray<const Object*> arguments(kNumArguments); |
| 781 arguments.Add(&Integer::Handle(Integer::New(port_id))); |
| 782 Dart_Handle result; |
| 783 InvokeStatic(isolate, function, arguments, &result); |
| 784 return result; |
| 785 } |
| 786 |
| 787 |
| 788 DART_EXPORT Dart_Port Dart_GetMainPortId() { |
| 789 Isolate* isolate = Isolate::Current(); |
| 790 ASSERT(isolate); |
| 791 return isolate->main_port(); |
| 792 } |
| 793 |
677 // --- Scopes ---- | 794 // --- Scopes ---- |
678 | 795 |
679 | 796 |
680 DART_EXPORT void Dart_EnterScope() { | 797 DART_EXPORT void Dart_EnterScope() { |
681 Isolate* isolate = Isolate::Current(); | 798 Isolate* isolate = Isolate::Current(); |
682 ASSERT(isolate != NULL); | 799 ASSERT(isolate != NULL); |
683 ApiState* state = isolate->api_state(); | 800 ApiState* state = isolate->api_state(); |
684 ASSERT(state != NULL); | 801 ASSERT(state != NULL); |
685 ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(), | 802 ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(), |
686 reinterpret_cast<uword>(&state)); | 803 reinterpret_cast<uword>(&state)); |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1544 DARTSCOPE(Isolate::Current()); | 1661 DARTSCOPE(Isolate::Current()); |
1545 const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object)); | 1662 const Closure& obj = Closure::CheckedHandle(Api::UnwrapHandle(object)); |
1546 const Integer& smrck = Integer::Handle(Integer::New(value)); | 1663 const Integer& smrck = Integer::Handle(Integer::New(value)); |
1547 obj.set_smrck(smrck); | 1664 obj.set_smrck(smrck); |
1548 } | 1665 } |
1549 | 1666 |
1550 | 1667 |
1551 // --- Methods and Fields --- | 1668 // --- Methods and Fields --- |
1552 | 1669 |
1553 | 1670 |
1554 // NOTE: Need to pass 'result' as a parameter here in order to avoid | |
1555 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' | |
1556 // which shows up because of the use of setjmp. | |
1557 static void InvokeStatic(Isolate* isolate, | |
1558 const Function& function, | |
1559 GrowableArray<const Object*>& args, | |
1560 Dart_Handle* result) { | |
1561 ASSERT(isolate != NULL); | |
1562 LongJump* base = isolate->long_jump_base(); | |
1563 LongJump jump; | |
1564 isolate->set_long_jump_base(&jump); | |
1565 if (setjmp(*jump.Set()) == 0) { | |
1566 const Array& kNoArgumentNames = Array::Handle(); | |
1567 const Instance& retval = Instance::Handle( | |
1568 DartEntry::InvokeStatic(function, args, kNoArgumentNames)); | |
1569 if (retval.IsUnhandledException()) { | |
1570 *result = Api::ErrorFromException(retval); | |
1571 } else { | |
1572 *result = Api::NewLocalHandle(retval); | |
1573 } | |
1574 } else { | |
1575 SetupErrorResult(result); | |
1576 } | |
1577 isolate->set_long_jump_base(base); | |
1578 } | |
1579 | |
1580 | |
1581 // NOTE: Need to pass 'result' as a parameter here in order to avoid | |
1582 // warning: variable 'result' might be clobbered by 'longjmp' or 'vfork' | |
1583 // which shows up because of the use of setjmp. | |
1584 static void InvokeDynamic(Isolate* isolate, | |
1585 const Instance& receiver, | |
1586 const Function& function, | |
1587 GrowableArray<const Object*>& args, | |
1588 Dart_Handle* result) { | |
1589 ASSERT(isolate != NULL); | |
1590 LongJump* base = isolate->long_jump_base(); | |
1591 LongJump jump; | |
1592 isolate->set_long_jump_base(&jump); | |
1593 if (setjmp(*jump.Set()) == 0) { | |
1594 const Array& kNoArgumentNames = Array::Handle(); | |
1595 const Instance& retval = Instance::Handle( | |
1596 DartEntry::InvokeDynamic(receiver, function, args, kNoArgumentNames)); | |
1597 if (retval.IsUnhandledException()) { | |
1598 *result = Api::ErrorFromException(retval); | |
1599 } else { | |
1600 *result = Api::NewLocalHandle(retval); | |
1601 } | |
1602 } else { | |
1603 SetupErrorResult(result); | |
1604 } | |
1605 isolate->set_long_jump_base(base); | |
1606 } | |
1607 | |
1608 | |
1609 DART_EXPORT Dart_Handle Dart_InvokeStatic(Dart_Handle library_in, | 1671 DART_EXPORT Dart_Handle Dart_InvokeStatic(Dart_Handle library_in, |
1610 Dart_Handle class_name_in, | 1672 Dart_Handle class_name_in, |
1611 Dart_Handle function_name_in, | 1673 Dart_Handle function_name_in, |
1612 int number_of_arguments, | 1674 int number_of_arguments, |
1613 Dart_Handle* arguments) { | 1675 Dart_Handle* arguments) { |
1614 Isolate* isolate = Isolate::Current(); | 1676 Isolate* isolate = Isolate::Current(); |
1615 DARTSCOPE(isolate); | 1677 DARTSCOPE(isolate); |
1616 // Finalize all classes. | 1678 // Finalize all classes. |
1617 const char* msg = CheckIsolateState(isolate); | 1679 const char* msg = CheckIsolateState(isolate); |
1618 if (msg != NULL) { | 1680 if (msg != NULL) { |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 } | 2359 } |
2298 delete debug_region; | 2360 delete debug_region; |
2299 } else { | 2361 } else { |
2300 *buffer = NULL; | 2362 *buffer = NULL; |
2301 *buffer_size = 0; | 2363 *buffer_size = 0; |
2302 } | 2364 } |
2303 } | 2365 } |
2304 | 2366 |
2305 | 2367 |
2306 } // namespace dart | 2368 } // namespace dart |
OLD | NEW |